Adding actions to buttons in a subview - button

in my app i call a UIView and that UIView is like a settings screen in my app and i have buttons in the UIView and my question is how do i add actions to the buttons iv added to the UIViews subview? thanks,

Assuming you're writing code in a view controller for your settings UIView, the UIView is properly bound to the view property of your controller, and you have referenced one of the buttons with a variable button, here is what you would write:
- (void)viewDidLoad {
[super viewDidLoad];
[button addTarget:self
action:#selector(buttonPressed)
forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonPressed
{
// do things here in response to the button being pressed
}
Another way to write that method is passing in a pointer to the button which was actually pressed, like so:
- (void)viewDidLoad {
[super viewDidLoad];
[button addTarget:self
action:#selector(buttonPressed:) // note the extra colon here
forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonPressed:(id)sender
{
UIButton *buttonWhichWasPressed = (UIButton *)sender;
// now you can do things like hide the button, change its text, etc.
}
Rather than calling addTarget:action:forControlEvents:, though, in Interface Builder (you should be doing this) after defining the buttonPressed or buttonPressed: method above, in the .xib file with the button go to the second tab in the Inspector after clicking on the Button (it should say Button Connections), and click-drag the Touch Up Inside event to File's Owner, and select "buttonPressed" from the list.

Related

UIButton to Navigation title

I have Two ViewController with Navigation controller,
and i want to press different button to change to next page and Next title also change when i hit a different button?
used this method??
- (void)viewDidLoad {
if Button == A;{
self.title = #"A";
}else Button == B {
self.title = #"B";
}
- (IBAction)A:(id)sender {
self.title =#"A";
}
- (IBAction)B:(id)sender {
self.title =#"B";
}
I know this is a wrong way, cause it just change first page title,but i want to change the second page only,and i just want to description that what i want to do,
please help,
Thanks
Pass your string (Which you want to set on next View Controller) from your first view controller to next view controller and put this self.title = Your passed string in next view controller's viewDidLoad()

How do I set up a Tab Bar Controller within an existing Navigation Controller?

I'm pretty new to iOS. I'm building an app and am running into an issue. I have a navigation controller with a table view controller atop its stack. When I select a row in that table view controller, what I'd like to see is a collection view with the following:
The nav bar with the name that appears on the selected cell as the navigation item title.
A collection view as the main interface
a tab bar with the collection view, and an imagePickerController
Here's what my code looks like:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NewTabBarController *tbc = [[NewTabBarController alloc] init];
UIImagePickerController *takeAPicture = [[UIImagePickerController alloc] init];
UITabBarItem *tabItem = [takeAPicture tabBarItem];
[tabItem setImage:[UIImage imageWithContentsOfFile:#"CameraIcon.jpg"]];
[tabItem setTitle:#"Take a photo!"];
UICollectionViewFlowLayout *photoFlow = [[UICollectionViewFlowLayout alloc] init];
PhotoCollectionViewController *photoHub = [[PhotoCollectionViewController alloc] initWithCollectionViewLayout:photoFlow];
[tbc setViewControllers:[NSArray arrayWithObjects:photoHub, takeAPicture, nil]];
NSArray *items = [[items accessor] allItems];
Item *item = [items objectAtIndex:[indexPath row]];
[photoHub setItem:item];
[photoHub useLayoutToLayoutNavigationTransitions];
[[self navigationController] pushViewController:tbc animated:YES];
}
Then in my PhotoCollectionViewController implementation I have:
#syntesize item;
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationItem *itemHeader = [self navigationItem];
[itemHeader setTitle:[item itemName]];
UITabBarItem *tabItem = [self tabBarItem];
[tabItem setImage:[UIImage imageWithContentsOfFile:#"itemImage.jpg"]];
[tabItem setTitle:[NSString stringWithFormat:#"Photos of %#", [item itemName]]];
}
My problem is that when I select the cell, The collection view loads, and I can see the cells I have set up in the collection view, but the nav bar item has no title, and the tab bar item has "Photos of (null)" and no image. The "Take a photo!" text appears, but the image does not.
Do you guys have any idea how I can restructure this to make everything flow correctly. I must be doing something wrong in the way I'm utilizing tab and nav controllers.I don't want there to be any tabs until this stage in the app, which is 3 or 4 VCs in already. Should I be using a tab bar controller from the App Delegate onward?
The problem here is that you are pushing tab bar controller onto a navigation controller stack. The view controllers of a tab bar will have a navigation item, but their navigation items aren't shown when the view controller is on screen. Instead, the tab bar controller's navigation item is on screen.
You could use self.tabBarController.navigationItem, but then each view controller will have to modify the navigation item every time it's brought on/off screen, which is really messy.
If you're going to use a UITabBarController, I would recommend either presenting it modally, or having it be the root view controller on your UIWindow. It's tough to get it working right as a view controller in a navigation controller's view controller stack.
Your tab bar item not showing its name is a separate issue. It's because viewDidLoad is getting called before you set your item instance, specifically it's getting called when you call [tbc setViewControllers:[NSArray arrayWithObjects:photoHub, takeAPicture, nil]];
You can confirm this by breakpointing in view did load, where you'll see that item is nil. If you haven't already, you should overload your setItem: method in PhotoCollectionViewController, and have that method also update your UI.

UINavigationCotroller backBarButtonItem with other target than self

I am trying to change the action executed by pressing the backBarButtonItem of a Navigation Controller.
I know that i have to edit the backBarButtonItem before the next view (on which the button with custom behavior should appear) is pushed. So in the previous ViewController i added the following code, to push via segue:
#pragma mark - segue methods
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"SettingsToProfile"]) {
MyProfileViewController* myprofileVC = [segue destinationViewController];
myprofileVC.myProfile = myProfile;
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Settings_" style:UIBarButtonItemStylePlain target:myprofileVC action:#selector(popTOSettingsViewController:)];
} else {
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Settings" style:UIBarButtonItemStylePlain target:nil action:nil];
}
}
The title "Settings_" gets displayed correctly, but "target: myprofileVC action:#selector(popTOSettingsViewController:)" doesn't seem to have any effect at all.
Background:
MyProfileViewController is a View, where the user can edit his/her own information. Whenever the backbarbutton is clicked, i want to check if something in the GUI has been changed by the user. If thats the case, a UIAlterView should ask the user, if he/she wants to save the changing. I tried to work it out with, viewWillDissappear, but the AlterView gets displayed in the next ViewController (and program crashes, if i click on the alterViewButtons).
I'm not sure that you can change the target of a backBarButtonItem. How about self.navigationItem.leftBarButtonItem instead? There's a discussion at self.navigationItem.backBarButtonItem not working ?? Why is the previous menu still showing as the button? that may be relevant.

How to pass an NSString from modal view to parent view

I have a parent view and a modal view with a text box. What I am trying to do is pass whatever is entered into the text box from the modal view and then pass it to a label in the parent view which updates the label to what was entered. I hope that made any sense.
I have been pulling my hair out for a couple of weeks trying to figure this out with no luck. I found many examples and tutorials about segues and passing between views that are being pushed but nothing about modal views and passing back to the parent view.
I have been trying to understand this and need a good example. I kind of understand the prepare for segue concept but for some reason, I just can't figure this one out. Any help on this would be much appreciated and you would be my hero for life lol.
In my project that uses segues, here's how I did it (note that I'm new to iOS, so there's probably "better" ways, and this may be obvious to the iOS veterans):
The short version: define a callback protocol in your modal view controller's .h file. When your modal view controller closes, it checks to see if the presenter implements that protocol and invokes those methods to pass along the data.
So like you said, let's say your modal view controller just gathers a single string value from the user and then they click OK or Cancel. That class might look like this:
#interface MyModalViewController : UIViewController
...
#end
I'm suggesting you add a protocol like this to the same header:
#protocol MyModalViewControllerCallback
-(void) userCancelledMyModalViewController:(MyModalViewController*)vc;
-(void) userAcceptedMyModalViewController:(MyModalViewController*)vc
withInput:(NSString*)s;
#end
Then in MyModalViewController.m, you add a viewDidDisappear with code similar to this:
-(void) viewDidDisappear:(BOOL)animated {
UIViewController* presenter = self.presentingViewController;
// If the presenter is a UINavigationController then we assume that we're
// notifying whichever UIViewController is on the top of the stack.
if ([presenter isKindOfClass:[UINavigationController class]]) {
presenter = [(UINavigationController*)presenter topViewController];
}
if ([presenter conformsToProtocol:#protocol(MyModalViewControllerCallback)]) {
// Assumes the presence of an "accepted" ivar that knows whether they
// accepted or cancelled, and a "data" ivar that has the data that the
// user entered.
if (accepted) {
[presenter userAcceptedMyModalViewController:self withInput:data];
}
else {
[presenter userCancelledMyModalViewController:self];
}
}
[super viewDidDisappear:animated];
}
And finally in the parent view, you implement the new #protocol, e.g. in the .h:
#interface MyParentViewController : UIViewController <MyModalViewControllerCallback>
...
#end
and in the .m:
#implementation MyParentViewController
...
-(void) userCancelledMyModalViewController:(MyModalViewController*)vc {
// Update the text field with something like "They clicked cancel!"
}
-(void) userAcceptedMyModalViewController:(MyModalViewController*)vc
withInput:(NSString*)s {
// Update the text field with the value in s
}
...
#end

storyboard navigation Item link to a uiviewcontroller

I create a split view project, on the iPhone's storyboard, i drag a bar button item to the navigation right and change the style Add, and i drag a view controller to the storyboard, so i use control-drag to build the link, and change the uiviewcontroller's custom class "AddViewController", when i run the project and push the DetailViewController, it is black view.
And i have input the code on the AddViewController.m
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"AddViewController"];
[vc setModalPresentationStyle:UIModalPresentationCurrentContext];
[self presentModalViewController:vc animated:YES];
}
i found the reason
On the my create "AddCreateViewController", i should comment the function.
- (void)loadView
{
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}

Resources