I have a subclass based on UIView and i want to change the tint of the uinavigationbar but various methods I've tried haven't worked. How do i do this?
As long as the view is in a viewController that's part of the navigation stack you can do:
viewController.navigationController.navigationBar.tintColor = [UIColor blackColor];
To access the viewController, you can declare an id as an ivar in your View class:
id myParentViewController;
Declare this id as a property so it can be accessed from outside the View.
When creating the view from the viewController, you could pass a reference to the viewController into the view by doing:
view.myParentViewController = self;
Where self would be the reference to your viewController on the navigation stack.
Now that you're in the view, you can access the navigation bar by doing this:
if([myParentViewController isKindOfClass:[UIViewController class]])
{
UIViewController *theParentViewController = (UIViewController*)myParentViewController;
theParentViewController.navigationController.navigationBar.tintColor = [UIColor blackColor];
}
You can access UINavigationBar from UINavigationController. One method is pass the UINavigationController or UINavigationBar as a parameter to the UIView. Or the UIView can use delegate to notify the outer UIViewController to do works.
Related
I have a view controller instance created with instantiateViewControllerWithIdentifier like this:
TBSCTestController* testController = [self.storyboard instantiateViewControllerWithIdentifier: #"OTP"];
TBSCTestController has an IBOutlet property named label which is hooked up with a label in the storyboard:
I want to modify the text of label using this code but nothing changes:
testController.label.text = #"newText";
[self.view addSubview: testController.view];
The testController is a valid instance but the label is nil.
What did i miss?
Your UILabel is nil because you have instantiated your controller but it didn't load its view. The view hierarchy of the controller is loaded the first time you ask for access to its view. So, as #lnafziger suggested (though it should matter for this exact reason) if you switch the two lines it will work. So:
[self.view addSubview: testController.view];
testController.label.text = #"newText";
As an example to illustrate this point, even this one would work:
// Just an example. There is no need to do it like this...
UIView *aView = testController.view;
testController.label.text = #"newText";
[self.view addSubview: testController.view];
Or this one:
[testController loadView];
testController.label.text = #"newText";
[self.view addSubview: testController.view];
I need to push a UIView into my UINavigation controller. I am doing it by
[self.view addSubview:showContactFlow];
And on a button click in UIView I need to push another UIViewController over the UIView. From the UIView I am not able to access self.navigationcontroller How can I do this?
Edit:
I have set the UIView as the view of a new UIViewController I am pushing into, the before mentioned UIViewController . Now I would like to know, how to handle the UIView button event inside its UIViewController, in which's view it is set.
Add a UINavigationController ivar to the UIView and assign it to the main view controller's. Then you should be able to access it from the UIView.
Edit:
Your UIView subclass:
// CustomView.h
#interface CustomView: UIView {
// ...
// your variables
// ...
UINavigationController *navController;
}
#property (nonatomic, assign) UINavigationController *navController; // assign, because this class is not the owner of the controller
// custom methods
#end
// CustomView.m
#implementation Customview
// synthesize other properties
#synthesize navController;
// implementation of custom methods
// don't release the navigation controller in the dealloc method, your class doesn't own it
#end
Then before the [self.view addSubview:showContactFlow]; line just add [showContactFlow setNavController:[self navigationController]]; and then you should be able to access your hierarchy's navigation controller from your UIView and use it to push other UIViewControllers.
You should try to work with an MVC approach. So your controller has access to all that stuff and can keep pushing and popping views, so the view doesn't need to know too much about the controller.
Otherwise, and for this case you can solve it fast by using delegation. So:
showContactFlow.delegate = self;
[self.view addSubview:showContactFlow];
So later in the UIView, you can just say:
[self.delegate addSubview:self];
This is gonna work, but it's not likely to be the best approach you should use.
On button click, you can present a view controller like,
-(void)buttonFunction{
ThirdVC *third= [[ThirdVC alloc]initWithNibNme];......
[self presentViewController:third animated:NO];
}
Using Core animation you can make NavigationController's pushviewController like animation on writing code in ThirdVC's viewWillAppear: method.
where do you add the UIButton is it in showContactFlow view or in the ViewController's view??
In regard to the modalViewControllers issue the correct method is
[self presentModalViewController:viewController animated:YES];
the standard animation in upwards
Bit confused with this one so bear with me...
I have a Navigation-based project which is working fine. I'm trying to create my first custom UIView to make a couple of buttons which I will use in multiple places. One of the buttons needs to push a viewcontroller into the navigation when it's clicked but I'm not sure how to do this.
When I had the button set up within a view controller I was using:
LocationViewController *controller = [[LocationViewController alloc] initWithNibName:#"LocationViewController" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
but the self.navigation controller won't work now, will it? How do I access the navigation controller of the viewcontroller that this uiview will be added to?
Hope at least some of that makes sense, as I said it's my first go at subclassing the uiview and adding it to multiple pages so I'm a bit lost.
EDIT TO ADD - I have the button click events inside the custom UIView, so that is where I'm trying to change the viewcontroller from. Should I instead wire up the events in whichever viewcontroller I add the view to?
Usually your appDelegate has a UINavigationController property. You can access it in your custom view like this:
UINavigationController *navController = (MyAppDelegate *)[[[UIApplication sharedApplication]
delegate] navigationController];
But more effective way is to make delegate method for your custom view and handle button action in your viewController.
MyCustomView.h
#protocol MyCustomViewDelegate
#interface MyCustomView : UIView {
id<MyCustomViewDelegate> cvDelegate; }
#property(nonatomic, assign) id<MyCustomViewDelegate> cvDelegate;
#protocol MyCustomViewDelegate #optional
-(void)didClickInCustomView:(MyCustomViewDelegate*)view withData:(NSObject*)data;
#end
MyCustomView.m
- (void)myButtonClick:(id)sender
{
[self.cvDelegate didClickInCustomView:self withData:someData];
}
So now you can handle this event in any place where is your custom
view.
Add the button from the interface builder or from the view controller's viewDidLoad using code:
CGRect frame = CGRectMake(0, 0, 24, 24);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button addTarget:self action:#selector(handleMyButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
Then implement -(void)handleMyButton:(id)sender {}; in your view controller. Or you could instead write -(IBAction)handleMyButton:(id)sender {}; and link method and button using the interface builder.
Then inside the method just paste the block of code you posted above. If you started with the Xcode navigation controller template project it should work.
I think it's cleaner to hide the designated initializer initWithNibName: because it is an implementation detail.
When you say you are subclassing the UIView I don't know exactly what you mean. If you want to add another view controller with a custom view just use the UIViewController template and customize the XIB file, no need to subclass an UIView unless you are really modifying its behaviour, which I guess you are not. The view is a view, and the controller stuff like handling buttons should be in the controller.
The actual controller need to be in the navigation controller stack to be able to push another controller.
Or you can make a new navigation controller instance and push your LocationViewController.
I have a viewcontroller and i am adding a subviewcontroller in that. Now i want to set value for a string from subviewcontroller which is in its superviewcontroller.
Please Suggest some idea
Thank You
if you want to access superview use the statement said by Jhaliya,
If you want to access superviewcontroller property frm subviewcontrller property ,
use
id mainViewController = [self.view.superview nextResponder];
here mainViewController is the superviewcontroller reference.
There a parentViewController property in UIViewController class reference,
This property is used for navigation, tab bar, and modal view controller hierarchies.
The above syntax is used for when you are setting a view as subview to a parentviewcontroller
You can access the super view controller using the parentViewController property on every UIViewController.
UIViewController *parent = self.parentViewController;
You can use superView method of UIView to access its parrent.
UIView *mySuperView = [MySubView superView];
use superview property of UIView.
UIMyView* mySuperView = (UIMyView*) myView.superview ;
mySuperView.mytextString = #"Assign string to super view";
EDITED:
You could get the list of all your UIViewController by using methods of UINaigationController .
Also current visible controller and top view controller,
Read the documentation for UINavigationController .
This question already has answers here:
Get to UIViewController from UIView?
(29 answers)
Closed 8 years ago.
There is a way to get a view controller reference from a UIView object? I need something like this:
MyParentViewController *myParentViewController = [self.view.superview controller];
You can use the -nextResponder method to do it. According to http://developer.apple.com/library/ios/documentation/uikit/reference/UIResponder_Class/Reference/Reference.html#//apple_ref/occ/instm/UIResponder/nextResponder , "UIView implements this method by returning the UIViewController object that manages it (if it has one) or its superview (if it doesn’t)"
UIView does not have reference to UIViewController by default.You can add it to your UIView subclass and set it when you create UIView in UIViewController.
If you are looking for parent of the viewcontroller, each UIViewController has property parentViewController, but if you want to access this from UIView you need to first get to your UIViewController.
You can see example how to create reference to your UIViewController in your subclass of UIView and how/where to set it up in View Controller Programming guide for iPhone, see section Creating the View Programmatically in Defining a Custom View Controller Class, here is the example, for more details see the linked Metronome example.
- (void)loadView {
self.wantsFullScreenLayout = YES;
MetronomeView *view = [[MetronomeView alloc]
initWithFrame:[UIScreen mainScreen].applicationFrame];
view.metronomeViewController = self;
self.view = view;
self.metronomeView = view;
[view release];
}
In header:
#interface MetronomeView : UIView {
MetronomeViewController *metronomeViewController;
...
You can use
[(MyParentViewController *)[[self.view superview] nextResponder] doSomething];
You shouldn't save the reference to the view controller as it may change dynamically.
Traverse the responder chain every time you need it.
You can use the following:
UIViewController* yourViewController =
(UIViewController*)[(YourAppDelegate*)
[[UIApplication sharedApplication] delegate] viewController];