Displaying a button at the bottom when scroll up - objective-c

I'm a newbie to iOS and i'm trying to develop an application based on news.
In my application , I have a Root View Controller which is a Table View Controller to display news' title and news' images. Well, when users click on the table cell ,there is another View Controller to be displayed which is more detailed and scrollable.
In the View Controller,users can share the news in Facebook and Twitter so that i have two buttons at least. What i want to do is displaying these two button when users scroll up. When users scroll down,i want to make them disappear. There is something like in Pulse News. I have already looked Scroll View delegate methods,but i didn't make it work. How can i accomplish what i want to do ?
Thanks in advance.

Create button at the position where you want in scroll according to scroll position.
origin x of scrollview : scroll.frame.origin.x;
origin y of scrollview : scroll.frame.origin.y;
height of scrollview : scroll.frame.size.height;
width of scrollview : scroll.frame.size.width;
Now you can put the button as you wish on scroll view:
button = [[UIButton alloc] initWithFrame:CGRectMake(x,y,x1,y1);

UPDATED WITH WORKING CODE: Outside of having the buttons scroll off the page so they are not visible
I know you said you looked at the scrollview delegates but this how you would solve this issue. In looking at Pulse the only tricky action is when you scroll down, which is when what look like UIToolbars fade away. The most important thing you need to have is anything that inherits from UIView at the very bottom and top of the visible screen of iPhone so when the user scrolls down or up the contentoffset has a value.
Every other actions cause them to appear sooo Pulse probably did something like this.
#import <UIKit/UIKit.h>
#interface C1ViewController : UIViewController
{
CGPoint _y;
}
#property (weak, nonatomic) IBOutlet UIScrollView *scroller;
#property (weak, nonatomic) IBOutlet UIToolbar *toolbar;
#end
#import "C1ViewController.h"
#interface C1ViewController ()
#end
#implementation C1ViewController
#synthesize scroller = _scroller;
#synthesize toolbar = _toolbar;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.scroller.contentSize = CGSizeMake(self.scroller.frame.size.width, self.scroller.frame.size.height + 100);
self.toolbar.hidden = TRUE;
_y = [self.scroller contentOffset];
}
// this method is getting deprecated, so don't worry about it to much
// but don't forget to dealloc...which I did not include.
- (void)viewDidUnload
{
[self setScroller:nil];
[self setToolbar:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"content offset %f", self.scroller.contentOffset);
if (_y.y < [self.scroller contentOffset].y){
self.toolbar.hidden = TRUE;
}
else {
self.toolbar.hidden = FALSE;
}
}
#end
What my view hierarchy looks like in Interface Builder

Related

UIImageView shifts left before animating to the right

Newbie here,
With this code in the .m file I aimed to animate an UIImageView to the right
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UIImageView *myImageView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[UIView animateWithDuration:1
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
self.myImageView.center = CGPointMake(self.myImageView.center.x + 100, self.myImageView.center.y);
}
completion:^(BOOL finished){
}];
}
But what actually happens is that the image view shifts 100 points to the left and then animates to the right by 100 points back to its original position. I don't know why this happens. How can I achieve an animation that moves directly to the right?
Note: I'm not sure if this has to do with anything, but I added constraints in the interface builder to center this UIImageView in the middle.
Create IBOutlets for the constraints you want change. Just like you would for any other UIKit element. Then in your code instead of doing:
self.myImageView.center = CGPointMake(self.myImageView.center.x + 100, self.myImageView.center.y);
Do something like this:
self.imageViewTralingSpaceConstraint.constant = 100; //Or whatever value makes sense
Then in your animateWithDuration block add [self.view layoutSubViews];
you probably want to put this code in your viewDidAppear method rather than your viewDidLoad. this would make the animation happen after the view appears rather than before it. the viewDidLoad method is called after the view hierarchy is loaded into memory but not neccessarily after it is all laid out.
here is a link to the uiviewcontroller reference. https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
check out these two methods there. if you continue doing iOS development you will get to know these methods really well.

NSScrollView how to start from top left corner

How to set scrollView document view to be pinned to top left corner? If scrollView is big enough/bigger than its content, everything is drawn from bottom to up and it not looks right. I have to override isFlipped of scrollView?
I was searching internet and overriding isFlipped to return trueis not everything. I don't want to make my documentView flipped because then I have to make changes in that class to make everything looks like I want.
I created simple NSView class as an container for elements that i want to have inside my scrollView and everything looks perfect. I hope this will help someone!
#interface FlippedView : NSView
#end
and implementation:
#implementation FlippedView
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Drawing code here.
}
- (BOOL) isFlipped
{
return YES;
}
#end
Swift 4 Method to invert axises :
from https://stackoverflow.com/a/40381180/5464805 thank's to Ben Leggiero :
import Cocoa
class FlippedView: NSView {
override var isFlipped: Bool { return true }
}
Then in the storyboard, set this class to the NSView below the NSClipView and it do the trick.
However it won't appear in StoryBoard so you'll have to build and run

Perform segue from main view on container view

I seem to be unable to understand how to go about this. I have a button on my main view. This view contains a container view. I would like the button on the main view to make the container view segue to another view. I have set up an identifier for the segue, which goes from containerView1 to containerView2. This is a push-segue. The identifier is pushSegue.
On the button on the main view I have tried this:
- (IBAction)btnChangeLocation:(UIButton *)sender {
UIViewController *a = [[ContainerView1 alloc]init];
[a performSegueWithIdentifier:#"pushSegue" sender:nil];
}
I have successfully performed this segue from within containerView1, by just placing within it, and performing the segue from there. It works just fine then.
- (IBAction)testButton:(UIButton *)sender {
[self performSegueWithIdentifier:#"pushSegue" sender:nil];
}
But how would I go if I wanted to trigger the segue on the containerView1, from the button on the main view?
Thanks.
EDIT:
I would also like to be able to perform the same segue, from a container view, that is within the container view.
Just to summarize.
MainView----->ContainerView1-->pushSegue--->ContainerView2
ContaainerView1 has a subContainerView, which also has a button, which causes ContainerView1 to segue into ContainerView2. This button and the button on the MainView does the same thing really, just from different "locations".
EDIT: Added a picture to help explain. http://tinypic.com/r/maxpp2/8
With UIViewController *a = [[ContainerView1 alloc]init]; you are instantiating a new ContainerView1 controller. That won't help you; you need to call performSegueWithIdentifier:sender: on the instance already created.
Depending on how your Storyboard and code are set up, you need to find a way to get a hold of the embedded view controller.
For this set up:
You could do something like this in the main (hosting) view controller:
#property (weak, nonatomic) IBOutlet UIView *childView;
#property (weak,nonatomic) UINavigationController *container;
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"embedContainer1"]) {
self.container = segue.destinationViewController;
}
}
-(IBAction)doIt:(id)sender {
[self.container.viewControllers[0] performSegueWithIdentifier:#"pushSegue" sender:nil];
}
By implementing prepareForSegue:sender:, you're able to get a reference to the child viewcontroller; cleaner then going through the array of childViewControllers IMHO.

How to change the color of the navigation bar in more than one table view controller

I am trying to figure out how to change the color of the table view navigation bar in multiple table views. The table views are all connected to a navigation controller. For example, I want one navigation bar to be blue, but another to be red. I have tried the code below in the AppDelegate.m file, but it just changes all the navigation bars to the same color. Is there anywhere else I could place this code to change the color in specific places. I've heard that I need to create new files, but I don't know where to place the code, or what code to use in the new files. I am somewhat new to this. Any suggestions would be greatly appreciated![[UINavigationBar appearance] setBarTintColor:[UIColor orangeColor]];
One way to do it, in your table view controller:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// set navigation bar's tint color when being shown
self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
}
You can add a property to make the view controller re-usable. Typically, you'd set the property in the prepareForSegue method of the pushing view controller:
#interface MyViewController ()
#property (strong, nonatomic) UIColor *toolbarTintColor;
#end
#implementation MyViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (self.toolbarTintColor) {
self.navigationController.toolbar.barTintColor = self.toolbarTintColor;
}
}
And finally, another approach is to implement the UINavigationControllerDelegate protocol and set the color in willShowViewController:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
UIColor *barTintColor = ...// your logic for determining the color for the given controller
navigationController.toolbar.barTintColor = barTintColor;
}
You can do this in the pushing view controller if, for some reason, you don't want to do it in viewWillAppear of the pushed view controller.

Set Scroll Boundaries UIWebView

I have a UIWebView which displays a webpage. The problem is I only want it to display a part of the webpage. I tried using [[_menuWebView scrollView] setContentOffset:CGPointMake(0, 100)]; to set the content offset to where I want it, but the problem is that I don't want the user to be able to scroll around the rest of the webpage. I also cannot set the webpage to not be scrollable because the part that I need to be able to be seen is slightly bigger than the space available. Is there a way to either:
Resize the view to only show one small portion so I can set it to not be scrollable
Set the scrolling boundaries in some way so that the user cannot scroll to the top of the page and not too far to the bottom either.
Thanks in advance!
EDIT:
I have used the code in the answer to get the UIWebView to not scroll past the top, the problem is getting it not to scroll past the bottom. I use this code to check where the contentOffset should be if it has hit the bottom: _bottom_y = [[_menuWebView scrollView] contentSize].height - 20 - [_menuWebView frame].size.height;. When I NSLog _bottom_y it comes up with 68 as where the bottom offset should be. The problem is that the top offset I know to be 115 and that works. What is wrong with the code above? Why is it giving me this weird number?
Thanks
I think this will be a good answer to your question. UIWebView in its structure contains an UIScrollView, that is why you can set your UIViewController to be a delegate of UIScrollView. Thus you can implement a method called scrollViewDidScroll: where you check if the UIWebView reached its y offset and if yes -> not let it scroll past that point.
Here is an example, that I have used:
#interface ViewController : UIViewController <UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_webView.scrollView.delegate = self;
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://google.com"]]];
_webView.scrollView.contentOffset = CGPointMake(0, 50);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y < 50) {
scrollView.contentOffset = CGPointMake(0, 50);
}
}
#end
Hope this helps, cheers!