How to perform performSegueWithIdentfier from within UIView - uiview

Ok so I have a UIButton embedded into a UIImageView which forms part of a UIView.
The button's selector calls a method which should run:
[self performSegueWithIdentifier:#"SegueToMoreInfo"];
However I get the error:
no visible at interface for 'myclassname' declares the selector 'performSegueWithIdentifier'.
Basically I really need to perform a segue from within the UIView. If not possible how would I call from the UIViewController instead?
EDIT: MORE INFO:
//adding button
UIButton *attractionButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[attractionButton addTarget:self
action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
[attractionButton setTitle:#"Attraction Info" forState:UIControlStateNormal];
attractionButton.frame = CGRectMake(80.0, 80, 160.0, 40.0);
[_image1 addSubview:attractionButton];
My method :
(IBAction)buttonClicked:(id)sender
{
[self performSegueWithIdentifier:#"SegueToMoreInfo" sender:sender];
}

[self performSegueWithIdentifier:#"aseguename" sender:self];
is a UIViewController method. That is why you are getting this error. Also views should not talk to ViewControllers except through protocols.
Having said that, you are going about this the wrong way. IBActions for buttons and other UIView objects should be in the ViewController. So I would move the IBAction to your View Controller and hook it to the button from there. Then insert your code in that IBAction.
Update after the code posted:
All of the code posted should be in your View Controller. I would just change:
[_image1 addSubview:attractionButton];
to
[self.view addSubview:attractionButton];
or if you really want that button to be a subview to your image, then you can leave your code, just make sure to create an IBOutlet property for that image, from your image in interface builder to your View Controller and call it _image1.
Hope this helps

Related

viewWithTag always returns nil in child view controller

I was using [self.view viewWithTag] in order to reference objects within a UIViewController. I then proceeded to move a specific subview to a new UIViewController, then adding it as a child view controller and adding the view as a subview. However, now I am unable to use viewWithTag within the child view controller to access different objects. Each time, the object retrieved using viewWithTag is nil.
I don't think that I am using viewWithTag improperly, as it was working fine before I moved that view to the new view controller. One solution is just to create properties for each of the views that I'm referencing using viewWithTag, but I do not think that this is a good way. Is there a better solution? Why is this happening?
Edit, as requested:
Here is how I add the child view controller:
self.runeTable = [RuneTableViewController new];
[self addChildViewController:self.runeTable];
self.runeTable.view.frame = CGRectMake(screenshotWidth + 32, navBarHeight, self.view.frame.size.width-screenshotWidth-32.0, self.view.frame.size.height-navBarHeight);
[self.view addSubview:self.runeTable.view];
Here is the code for creating the button:
UIButton *updateButton = [UIButton buttonWithType:UIButtonTypeCustom];
updateButton.tag = 5;
[updateButton setTitleColor:HIGHLIGHT_COLOR forState:UIControlStateNormal];
[updateButton.titleLabel setFont:FONT_MED_LARGE_BOLD];
[updateButton setTitle:#"Update" forState:UIControlStateNormal];
updateButton.frame = CGRectMake(283, 280-60, 100, 60);
[detailInnerView addSubview:updateButton];
And here in some other method, I am trying to retrieve and add a target to that button:
UIButton *updateButton = (UIButton *)[self.view viewWithTag:5];
[updateButton addTarget:self action:#selector(updateCurrentDictionaryWithRuneInfo) forControlEvents:UIControlEventTouchUpInside];
When I added breakpoint and po updateButton, it returned as nil. Same thing happened with other UI elements in the view controller that I also tried to retrieve in this manner.
I figured it out. updateButton is added to another UIView, which is added to the parent view controller. Thus, in order to retrieve updateButton I should be using [self.parentViewController.view viewwithTag:5] instead of [self.view viewWithTag:5].

UIButton click event crash after adding the viewcontroller's view as a sub view

I want to add several ViewController's views as sub views of my another viewcontroller. So I have done like this inside my parent viewController.
-(void)MakeDisplayArea
{
vwDisplayArea=[[UIView alloc] initWithFrame:CGRectMake(0, 0, w, h-scrolTab.frame.size.height)];
[self.view addSubview:vwDisplayArea];
}
-(void)ProfClick :(id)sender
{
[self MakeDisplayArea];
ProfileViewController *profviewcontroller=[[ProfileViewController alloc] initWithNibName:#"ProfileViewController" bundle:nil];
profviewcontroller.view.frame=vwDisplayArea.frame;
[profviewcontroller.view setBackgroundColor:[UIColor clearColor]];
[vwDisplayArea addSubview:profviewcontroller.view];
}
Then inside the profViewcontroller ViewDidLoad methods I am generating a button and set the target like this.
UIButton *btn=[[UIButton alloc] initWithFrame:CGRectMake(10, 60, 100, 30)];
[btn setTitle:#"Button Test" forState:UIControlStateNormal];
[self.view addSubview:btn];
[btn addTarget:self action:#selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
-(IBAction)btnClick :(id)sender
{
NSLog(#"button clicked-------");
}
I can see the button is appearing on that profViewcontroller that I loaded as a sub view, but when I click the button the app is crashing. What is the correct way add that viewcontroller as a subview on my first viewcontroller. Please help me.
Thanks
Like maddy said you need child view controllers to add working subviews.
Look here: Creating Custom Container View Controllers
But working with them is not easy. Ask yourself if you really need to implement it. For the most cases you don't need it.

When tapping a UIButton that was created programmatically is it possible to push to a controller that is editable in interface builder?

Created a UIButton programmatically but the page it needs to link to will need to be the root controller view of a UINavigationController.
This page would be easier to create in interface builder rather than in code. When the button in question is tapped it needs to segue to another controller/view that I can edit in interface builder.
Possible or impossible?
If possible how can I do this? I feel I'll run into this problem quite often.
You can do this :
Button creation:
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[btn addTarget:self action:#selector(btnMethod:) forControlEvents:UIControlEventTouchUpInside];
Button method:
- (void)btnMethod:(UIButton *)sender
{
[self performSegueWithIdentifier:#"MySegueIdentifier" sender:sender];
}
Sure it's possible:
Create the button:
UIButton *bottonOne = [[UIButton alloc]initWithFrame:CGRectMake(10, 15, 65, 12)];
The set it up with a title / image as you need. Once you have done that do this:
[buttonOne addTarget:self action:#selector(buttonOnepressed) forControlEvents:UIControlEventTouchUpInside];
Then in the same class create a method called buttonOnepressed
-(void)buttonOnePressed
{
//preform the steps needed for your segue method and anything else you want to do when the button has been tapped
}
Edit
After reading your comments - you want a button you've created in code, to perform a segue without manually invoking the segue (Writing code to actually show the new screen) and you want it to behave like it would if you did a drag and drop in IB. If that's the case - the short answer is simply, no. If you create a button in code, all its actions need to be done in code, too.
Edit 2
Try this:
In IB create a "generic" segue like this:
Ctrl-drag from the source view controller to the other view you want to do to when the button is tapped. You can use the view controller object at the bottom of the scene to do this.
Give the segue an identifier.
Then use [self performSegueWithIdentifier#"Your Identifier"]; in your button tapped method to perform the segue

programmat button and storyboard button

I have one button and one search field in navigation bar and i added a new button by code from one class for all view.
The problem is: with the button view the other button and the search field added with storyboard are not more touchable and not working.
UIImage * buttonImage = [UIImage imageNamed:#"chat-notify.png"];
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self
action:#selector(goChat)
forControlEvents:UIControlEventTouchDown];
//[button setTitle:#"1" forState:UIControlStateNormal];
button.frame = CGRectMake(280.0, 25.0, 30.0, 30.0);
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[self.view addSubview:button];
and then in the controller:
notificationViewController* notification = [[notificationViewController alloc]init];
//[notification methodA];
[notification makeButtonNotification];
[self.view addSubview:notification.view];
Does anyone know where is my mistake?
Thanks
Why are you adding the button surely having it there and changing it's hidden state would be easier then you can keep it all in the storyboard
UIControlEventTouchUpInside
is what you should use not "UIControlEventTouchDown"
TouchUpInside is usually the event where you trigger the action from a button. It's when the user is lifting up from the button after pressing it. You don't want to trigger the action on Touch Down as the use may move his finger off the button to cancel the press, which is standard and expected behaviour on iOS
UPDATE: Base on your comment to this answer perhaps you need to add the button to a specific point in your view heir achy. As in your storyboard views will be added as they are listed in that stroyboard starting from the top down, with the one on the bottom being the top view.
Try obviously making sure that views that you want to receive touches are not directly on top of each and that they do not overlap. Also try adding the programatically generated button above or below a specific view, rather than just making it the top subview in your main view which by the sounds of it isn't what you want.
As you're adding a button like this
[self.view addSubview:button];
it may be better to do it more like this
[self.view insertSubview:button aboveSubview:someOtherView]
To do this you'll probably need to hook up your "someOtherView" to an IBOutlet so you can reference it in your code. As it looks like you're most likely sticking your button over everything else, when you need to be more precise.

Why [UIBarButtonItem setCustomView:] method disable segue in Storyboard?

I have Storyboard in my project. I use [UIBarButtonItem setCustomView:] method to customize toolbar buttons. For example:
[self setCustomView:[[UIImageView alloc] initWithImage:image]];
Now they looks as I need. But I found that this method somehow disables segue that I set for this toolbar item. I mean, segue works without it, but when I tried to use this method for customization segue don't work. But why?
I don't want to use target-action pattern from code, I believe it is possible to use only Storyboard.
I've been trying to configure all of the segues in the storyboard as well but I needed to create a custom view for the rightBarButtonItem. To make sure the segue still works, just add this line before setting the customView:
[filterButton addTarget:self.navigationItem.rightBarButtonItem.target action:self.navigationItem.rightBarButtonItem.action forControlEvents:UIControlEventTouchUpInside];
This way the segues you set up in your storyboard will still fire with customViews.
My entire custom button code looks like this:
UIButton *filterButton = [UIButton buttonWithType:UIButtonTypeCustom];
[filterButton setImage:[UIImage imageNamed:#"filter"] forState:UIControlStateNormal];
[filterButton setFrame:CGRectMake(0, 0, 36, 36)];
[filterButton addTarget:self.navigationItem.rightBarButtonItem.target action:self.navigationItem.rightBarButtonItem.action forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.rightBarButtonItem.customView = filterButton;
I've tried what you have done with the same result - the picture is correct but the UIBarButtonItem doesn't react when pressed. Possibly this is a bug. My work around is as follows:
To do this in storyboard add a UIButton to the tool bar. You should see that storyboard adds it by putting the UIButton inside of the UIBarButton. Add the segue on the UIButton. Customize the UIButton in storyboard. In my App I set the size to 40 x 40. Then in your code customize the UIButton with the view. Here is an example of the code to add the imageView to the UIButton:
[sampleImageView setFrame:CGRectMake(0, 0, 40, 40)];
[swapButton addSubview:sampleImageView];
Note: Storyboard can be quirky about adding UIButtons to toolbars. It seems as if you do it in a toolbar that is tied to a navigation controller it won't let you add it. I've worked around this by adding a dummy view controller to the storyboard, adding a toolbar to that, then dragging the UIButton into that toolbar. Storyboard will create that for you by encapsulating the UIButton in a UIButtonBarItem. You can then copy then over to the the desired toolbar in your project and delete dummy view controller.
There are other ways to do this such as creating the buttons in code and adding them to the toolbar. The method above minimizes code.

Resources