TapGestureRecognizer on UIToolbarButton doesn't work - ios

I have a UIToolbarButton which has a UIButton to hold the image. Now, when I click on this UIToolbarButton, I want to open another view in the current view.
My Code :
- (IBAction)btnNowPlaying:(id)sender
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(openPlaying:)];
[self.view addGestureRecognizer:tap];
}
- (void)openPlaying:(UIGestureRecognizer *)sender
{
NewMainViewController *vc = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"Center"];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController * npvc = [storyboard instantiateViewControllerWithIdentifier:#"NowPlayingVC"];
[vc.containerView addSubview:npvc.view];
}
This action, btnNowPlaying is on the UIButton.

It sounds like you simply want to navigate from one view controller to another. Just control-drag from your bar button item to the view controller you'd like to navigate to in your storyboard. Then, click the segue between the two view controllers and set its identifier in the Attributes inspector. After that, all you need to do is implement prepareForSegue::
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"THE_IDENTIFIER_YOU_ENTERED_IN_THE_ATTRIBUTES_INSPECTOR"]) {
if ([segue.destinationViewController isKindOfClass:[NEWViewController class]]) {
NEWViewController *vc = (NEWViewController *)segue.destinationViewController;
// Any preparation you need to do for next view controller
vc.someProperty = someValue;
}
}
}
It's a little strange to open a new view controller inside the current view controller. Why not just segue to it?
Another option would be to alloc-init a UIView instead of a view controller and simply addSubview:.

First of all, you can use default UIBarButton item with Custom style and setter Image property instead of creating UIButton.
You don't need to create additional gesture recogniser. If you have connect IBAction with button in Interface Builder, you can put your transition code inside btnNowPlaying method.
Another way is to create IBOutlet, connect it with your button and create UIGestureRecognizer in - (void)viewDidLoad method.

Related

IOS 8 Objective-C Referencing storyboard from a UITableViewCell

I have a use case where essentially I have a image in a customized table view cell. When the user selects the image we want to send them to a Profile page.
Normally, I'd do this by
- (IBAction)userClickedProfilePic:(id)sender {
ProfileViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"Profile"];
vc.postInfo = self.newsfeedData.newsFeedPosts[indexPath.row];
[[self navigationController] pushViewController:vc animated:YES];
}
But self != have a storyboard reference in this case since it's a UITableViewCell class. Is there a way to pop or push a new viewController from a tableviewcell action?
You have plenty of options. What I usually do is that I will create IBAction in viewcontroller which "contains" tableview with its cells. You can create IBOutlets or IBActions in all parents viewcontrollers through IB in a same way you would do it for cell..you might didn't know that.
But you want to click event on uiimageview which is not so straitforward. You have to do it programatically but it's not that hard just do something like this in cellForRowAtIndexPath and implement actionMethod:
UITapGestureRecognizer *actionMethod = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(actionMethod:)];
[cell.yourImageView addGestureRecognizer:actionMethod];
By the way instead of self.storyboard you can use this in case your storyboard is named Main.storyboard.
[UIStoryboard storyboardWithName:#"Main" bundle:nil]

Button present a navigationViewController with a different embed viewContoller in the container

I have 3 different buttons which upon touch present the same UINavigationViewController with a container.
However, each button represents which view controller will be embed at the container.
How can I embed the necessary viewController by code?
what you can do is use an identifier which would be assigned to your various viewController as storyboardID
such as fisrtVC, SecondVC, thirdVC
the depending upon whichButton is pressed just set the identifier and use this identifier when
you want to push the controller such as
for example
while you push the navigation viewController just pass the storyboard Identifier such as
Declare a NSString *identifier;
-(IBAction)firstButtonClicked{
identifier=#"firstVC";
//pass this identifier to your navigationController
}
similarly for other Controllers
When you push the navigation controller make sure to pass this identifier along now depending upon the value you can initiate the controller on you VC as
on ViewDIdApppear:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
NSString* viewType = passedIdentifier
UIViewCOntroller* viewController = [storyboard instantiateViewControllerWithIdentifier:viewType];
Load this "viewCOntroller in your ContainerView"
You should implement prepareForSegue method:
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
id is your button that will fire segue. You do segues by drugging and drop in storyboard. Put an if statement in this method and tell your UIViewController which UIView to load in container. You can pass data like this:
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
Second snippet taken from this answer.
Update.
To load different UIView in container put if statement into viewWillApper method.
This method firing earlier than viewDidLoad. If statement must check some property that tell what UIView to init. You setting up this property in prepareForSegue.
It will look like this:
if (self.viewToLoad == 1)
{
self.dynamicView = MyCustonUIViewNumberOne *view = [MyCustonUIViewNumberOne alloc] init];
}
Update 2.
Or you can do it dynamically like in this answer:
if (self.viewToLoad == 1)
{
// Replacing with your dimensions
CGRect frame = CGRectMake(x, y, width, height);
MyCustonUIViewNumberOne *dynamicView = [[MyCustonUIViewNumberOne alloc] initWithFrame:frame];
[self.container addSubview: dynamicView];
} else {
// Init other view
}
The container property:

Segue to a UINavigation Controller programmatically without storyboards

I have code that uses Storyboards for seques, like so:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowDiagnosis"])
{
[segue.destinationViewController setHappiness:self.diagnosis];
}
...
But I want to do it programmatically. I have myViewController class and when I click on a button I want to animate and push to myUINavigationController.
How is this done programmatically?
First things first, a segue cannot be created programmatically. It is created by the storyboard runtime when it is time to perform. However you may trigger a segue, which is already defined in the interface builder, by calling performSegueWithIdentifier:.
Other than this, you can provide transitions between view controllers without segue objects, for sure. In the corresponding action method, create your view controller instance, either by allocating programmatically or instantiating from storyboard with its identifier. Then, push it to your navigation controller.
- (void)buttonClicked:(UIButton *)sender
{
MyViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"my-vc-identifier"];
// OR MyViewController *vc = [[MyViewController alloc] init];
// any setup code for *vc
[self.navigationController pushViewController:vc animated:YES];
}
First of all segue can be used only with if you have a UINavigationController that will handle the navigation (push, pop, etc).
So if you have a UINavigationController and you want to push another UIViewController on the stack without using segue then you can use pushViewController:animated: method which also has a reverse popViewControllerAnimated:. Also UINavigationController provides other methods for adding/removing UIVIewControllers, for more info check UINavigationController class reference.

How to programatically change views in iOS

In Xcode 4.5 you can change views from a segue, But I want to programatically change views in Mainstoryboard. I Know in Xib. we use this method:
SecondViewController *Second = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:Second animated:YES];
I want to change the view when the user clicks done in the textfield (This code detects if user clicks done):
-(IBAction)hidekeyboard {
[sender resignFirstResponder];
}
You create a segue in your storyboard that goes from the view that has the text field in question and goes to your SecondViewController. You have to assign an identifier to it (also in the storyboard, click on the line connecting the two view controllers), let's call it "segueToSecondViewController". Then, you can manually call the segue using:
[self.storyboard performSegueWithIdentifier:#"segueToSecondViewController" sender:self];
An alternative to segueing is to instantiate the viewController from the storyboard.
First you assign a Storyboard ID to the viewController in the storyboard.
Then you instantiate that viewController, and present it.
MBTagEditorViewController *tagEditor = [self.storyboard instantiateViewControllerWithIdentifier:#"TagEditor"];
[self presentModalViewController:tagEditor animated:YES];

UITableViewController loses scroll functionality if presented by a popover as model

Any reason why a model tableview (UITableViewController) is not scrolling a table when the keyboard appears ONLY if presented by a popover controller?
I basically have a popover menu with a button that opens a model Tableview fullscreen, text fields within rows at the bottom of the table get hidden by the keyboard when tapped.
This is not the same as a UIView or Scrollview where you have to manage scrolling manually. The UITableViewController has this functionality built in, it just doesn't work if there is a popover controller somewhere back down the hierarchy.
Sample project: www.geoffcoope.co.uk/ios/testTVCScrolling.zip
Thanks
Geoff
Either your UITableView is sending its delegate method requests to the popover's view controller instead of your UITableView controller, or your UITableView's delegate is set to nil. Look where you are instantiating your TableView and make sure you are setting the delegate property correctly.
I guess your problem is with a way a storyboard's segue shows popover controllers. It looks like it is a common problem.
So, the easiest way to solve it, is to move the creation of your modal window inside a code. Something like that:
Inside your ViewController.h write
#property (strong) UIPopoverController * popoverController;
- (void) showNavigationController;
Inside your ViewController.m write
#synthesize popoverController;
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[super prepareForSegue:segue sender:sender];
if ([segue isKindOfClass:[UIStoryboardPopoverSegue class]]){
if (popoverController) [popoverController dismissPopoverAnimated:NO];
UIStoryboardPopoverSegue * popoverSegue = (UIStoryboardPopoverSegue *) segue;
popoverController = popoverSegue.popoverController;
}
}
- (void) showNavigationController
{
[popoverController dismissPopoverAnimated:NO];
popoverController = nil;
UIStoryboard *ub = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *controller = [ub instantiateViewControllerWithIdentifier:#"navigationController"];
[self presentModalViewController:controller animated:YES];
}
then inside your MainStoryboard set identifier navigationController for your navigation controller and instead of segue on your "Show Table" button set a "touch up inside" delegate. This delegate will execute your showNavigationController method from ViewController (using a NSNotificationCenter, as example)

Resources