This question already has answers here:
Positioning UITabBar at the top
(9 answers)
Closed 7 years ago.
To preface, I just started iOS programming but do have a rather comprehensive background in Objective-C. So please explain what you are saying, but don't feel like you have to talk like a two year old.
I am building an application that uses a tabbed view controller. I want to move it to the top of the application like Facebook or Ask.fm do with their applications.
I know there have been other articles, but they are kind of old and I don't really understand them. So if you could provide some sample code with your answer that would be great.
All I want to do is move the bar, I don't want to create a new tabbed bar controller or something.
In iOS development, UITabBar is not for the top side. iOS divides each area in different sections, for example UINavigationBar is for top side part not for the footer same as UITabBar can only be use in footer according to Apple's recommendation.
You can use a custom view with the help of UIView and as many UIButtons in it as you want. Let's say you want to create top bar with two button so you can achieve this by doing this:
First, you have to hide UINavigationBar like this:
- (void)viewDidLoad {
[super viewDidLoad];
[[self navigationController] setNavigationBarHidden:YES animated:NO];
_topBar=[self createTopBar];
[self.View addSubview:_topBar];
}
after that you can create your own custom view like this:
- (UIView *)createTopBar {
UIView * topBar=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
UIButton * btnOne=[UIButton buttonWithType:UIButtonTypeCustom];
btnOne.frame=CGRectMake(0, 5, 34, 34);
[btnOne setBackgroundColor:[UIColor clearColor]];
[btnOne addTarget:self action:#selector(YourMethodOne) forControlEvents:UIControlEventTouchUpInside];
UIButton * btnTwo=[UIButton buttonWithType:UIButtonTypeCustom];
btnTwo.frame=CGRectMake(270, 5, 34, 34);
[btnTwo setBackgroundColor:[UIColor clearColor]];
[btnTwo addTarget:self action:#selector(YourMethodTwo) forControlEvents:UIControlEventTouchUpInside];
[topBar addSubview:btnOne];
[topBar addSubview:btnTwo];
}
-(void) YourMethodOne {
NSLog(#"First button Pressed");
//Do whatever you want when btnOne is pressed
}
-(void) YourMethodTwo {
NSLog(#"Second button Pressed");
//Do whatever you want when btnTwo is pressed
}
In this example I create a local method and a local variable. I prefer to create a proper class and your these button as public instance.
I am building an application that uses a tabbed view controller. I want to move it to the top of the application like Facebook or Ask.fm do with their applications.
You're confusing UITabBar and UITabBarController, which are entirely different classes. The former is a view, while the latter is a view controller, i.e. not a view at all. Also, perhaps because of that confusion, you're making assumptions about how other apps are implemented. Because the apps you mention put the tabs at the top, it's very unlikely that they use UITabBarController.
All I want to do is move the bar, I don't want to create a new tabbed bar controller or something.
UITabBarController manages an array of other view controllers that you provide, displaying view associated with the currently selected view controller, and it also manages a tab bar. How it lays out the views it manages (tab bar, selected view) is not customizable -- if you want a behavior that's different from what you get with UITabBarController, you need to use a different class.
Related
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
I want to developer app with a custom navigation bar like in the following images:
I think that i need to subclass UINavigationBar and add button to centre of nav bar, but i don't really know how to make navigation bar look like on image. Can you please give me advice what should i do, links to any kind of documentation would be awesome!
Similar questions about navBar that doesn't helped me:
ios back button in the bar
Use custom Navigation Bar in iOS
Custom Navigation Bar in iOS 5
rogcar
EDIT:
My idea is next: make custom navigation bar height little bigger than default size, and add background image with arrow in it and with some transparency on the edges.
If you want a button (you probably do want) you can achieve it completely by subclassing UINavigationBar. You should remember that height of UINavigationBar is read-only property.
Style but not tappable:
So let's assume we subclass the navigation bar and add button there. You could do this and it will be going look great. For example:
- (void)drawRect:(CGRect)rect
{
self.backgroundColor = [UIColor lightGrayColor];
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(self.frame.size.width/2-50, 0 , 100, 100)];
[myButton setBackgroundColor:[UIColor lightGrayColor]];
[myButton setTitle:#"Normal" forState:UIControlStateNormal];
[myButton setTitle:#"Highlighted" forState:UIControlStateHighlighted];
[self addSubview:myButton];
[self sendSubviewToBack:myButton];
}
But you will facing a problem that your button is non tapeable below UINvaigationBar. (I post an image on the bottom of the answer)
So there is clearly not a path you want to follow. Don't even try that.
Style but not tappable 2:
You may override this method in your navigation bar subclass
- (CGSize) sizeThatFits:(CGSize)size {
return CGSizeMake(custom_width, custom_height);
}
And then mask it using UIBezierPath for example
The right (tappable) way:
You have to create a view stick to your UINavigationBar. What i will do here (if you want it to every screen) is:
Make a Category of UIViewController which can draw (for example - this is easiest way) UIButton.
Style this 'UIButton' whatever you want (if you want
Pin action to 'UIButton': [btn addTarget:self action:#selector(menuShow:) forControlEvents:UIControlEventTouchUpInside];
menuShow: method should be declare in your category
You can call drawing button every time you want to redraw view controller.
As you can see there there will be two separates View: UINavigationBar and UIButton. This is allow you to set content under this little button and make it tapable.
So why just don't hide navigation bar, and use different view? Because iOS7 ;) When Apple change it in iOS7 for example then you have to rebuild your pseudo NavigationBar, with only additional view, you don't need to do anything.
You do not need to subclass UINavigationBar. Create UIView add to it UIImageView as background with image in the shape you need, add button.
Subclass UINavigationController hide UINavigationBar, add custom navigation bar.
First Hide navigation bar using -
self.navigationController.navigationBarHidden = YES;
Then create UIView with required height,height of navigationBar is 44px.Then create background image view, object of required UIButton and add all objects on created UIView as a subview.It will look like navigationBar.Thank you.
You can add your custom shaped view as titleView on the navigation bar.
Just make sure that clipsToBounds is set to NO, so it doesn't get clipped.
I know this question is worded kind of strangely, but let me explain what I'm trying to do:
Let's say that I have an app with 2 tabs, each with their own view. Both views are almost exactly the same, except one contains a button or two that the other one doesn't, and vice versa.
I already made one view in Storyboard mode, now I want to change just a little tiny bit about it and reuse the same view for the other tab.
I don't want to do a deep copy, because if I change one, then I would have to change the other, and that might cause some inconsistency between the two.
So how should I go about using the same generic view for multiple tabs, and just change little things about it depending on which tab I am in?
Should I add the universal content in storyboard view, and then programmatically add the particular tab-exclusive content? If I did this, I would need a way to detect what tab is selected, right? Is there a way to do that?
Thank you for any suggestions!
You don't need a Storyboard for that. Sure you can drag a view in there and assign it to a specific class and program all stuff in that, but if you really need only one view in there the storyboard is useless. You should deal with subviews programmatically if you want to change something. This is very good and you have great features like animationWithDuration:
For checking which Tab in your UITabBarController is selected you can use self.tabBarController.selectedIndex and compare it with the given Index of the Tab which is selected.
EDIT:
If we assume you have a green Button on Tab with index 0, and the same Button should slide a little bit above and a red Button should appear where green Button when Tab with index 1 is tapped.
UIButton *greenButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 320, 100, 20)];
greenButton.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenButton];
UIButton *redButton = [[UIButton alloc] initWithFrame:CGRectMake(0, greenButton.frame.origin.y, 100, 20)];
greenButton.backgroundColor = [UIColor redColor];
if (self.tabBarController.selectedIndex == 1) {
[UIView animateWithDuration:1.0 animations:^{
greenButton.frame = CGRectMake(0, 300, 100, 20);
} completion:^(BOOL finished) {
[self.view addSubview:redButton];
}];
}
First you create the two buttons and add the green one to the view. (The first view is at index 0). Then you check if the selectedIndex is 1 and animate the Buttons around.
I'm stuck on a concept in iOS that I can't seem to understand, no matter how much I read about it. I'm trying to override the standard iOS number pad with a custom design. When the user touches the UITextField, I want the custom inputView to reveal instead of the standard number pad.
I created an separate .h/.m/.xib ViewController class for my custom inputView called "customInputViewController" Right now, it's just a dark background and one button that obscures about half of the screen when the UITextField is touched (similar to the number pad, but it just looks different). My implementation fails when I click the one button in my custom inputView -- iOS throws an EXC_BAD_ACCESS error.
This is how I load the .xib file at runtime and attach the custom inputView to the UITextField object:
UIViewController *v = [[customInputViewController alloc] initWithNibName:#"customInputDesign" bundle:nil];
myTextInput.inputView = v.view;
In the .xib file of the custom inputView, I set the File's Owner to be "customInputViewController" and I created an (IBAction) method and attached it to a UIButton. When that button is clicked, the (IBAction) is set up to send an NSLog(#"Button Clicked") message. Nothing special. It's just a simple boilerplate implementation that continues to throw an error.
Maybe I'm doing this entirely wrong. Can anyone provide a simple example?
The view v.view is retained as the inputView property is defined as (readwrite, retain). However, if you release your customInputViewController v somewhere before the input button is clicked, you will get a crash (EXC_BAD_ACCESS)
You can try this in your main controller:
- (IBAction) keyboardButtonClicked
{
NSLog(#"keyboard Button Clicked");
}
- (void) viewDidLoad
{
// do your stuff here ...
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)]; // add autorelease if you don't use ARC
v.backgroundColor = [UIColor darkGrayColor];
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
[b setTitle:#"Test button" forState:UIControlStateNormal];
[b addTarget:self action:#selector(keyboardButtonClicked) forControlEvents:UIControlEventTouchUpInside];
b.frame = CGRectMake(80, 25, 160, 50);
[v addSubview:b];
myTextInput.inputView = v;
}
Should work fine ...
First of all, Take a look at this
The UIKit framework includes support for custom input views and input
accessory views. Your application can substitute its own input view
for the system keyboard when users edit text or other forms of data in
a view. For example, an application could use a custom input view to
enter characters from a runic alphabet. You may also attach an input
accessory view to the system keyboard or to a custom input view; this
accessory view runs along the top of the main input view and can
contain, for example, controls that affect the text in some way or
labels that display some information about the text.
To get this feature if your application is using UITextView and
UITextField objects for text editing, simply assign custom views to
the inputView and inputAccessoryView properties. Those custom views
are shown when the text object becomes first responder...
Actually i don't need to mention all this mess to you, but there is an interesting reason for mentioning this, from the first sentence i am mentioning view-view-view, but you are making the input view in a separate view controller and you are trying to assign it as an input view of your textfield and init shouldn't be creating the view, loadView does that. Calling the view getter (v.view) when view is nil will cause loadView to be invoked.Thats why it is crashing with EXC_BAD_ACCESS.
Source : Text, Web, and Editing Programming Guide for iOS
I have a Navigation Controller as the root of my app and I am using the appearance proxy to customise the look on iOS 5, but for iOS 4 I was hoping to use a category to override drawRect:, this was fine, except that all the Navigation bars were affected as you would expect from a category.
I don't want to tamper with the "system" popups, such as the Mail composer, or the SMS composer, I want their bars to stay blue and system-like.
I Tried to create my own UINavigationController with it's xib and change the class of the NavigationBar to my custom sub lass of UINavigationBar. But the results are not taking affect at all on screen.
I am aware of the following post but couldn't get any solutions to run as expected.
How to subclass UINavigationBar for a UINavigationController programmatically?
My first attempt which does work but uses an undocumented setNavigationBar: method:
_myNavigationController = [[UINavigationController alloc] initWithRootViewController:someVC];
if([[BT_NavigationController class] respondsToSelector:#selector(appearance)]){
// some iOS 5 magic in here !
[_myNavigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"topbar.png"];
}else{
// Probably looking at app store refusal
CustomBar * bar = [[CustomBar alloc] init];
// [_myNavigationController setNavigationBar: bar];
[bar release];
}
[parentView presentModalViewController:_myNavigationController animated:YES];
To avoid that I created a UINavigationController, which I also had a xib for, reassigning the class of the navigation bar to my custom class, but placing breakpoints in drawRect: method, I can see that this isn't being called.
Why would that be, it seems that my code is not loading the nib, and therefore not realising the nab bar should be my custom class and not the UINavigationBar.
Any tips would be helpful, thanks.
If your modification is just about adding an image, you can simply insert it from the view controllers you want to customize:
UIImageView *bgImageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"topbar.png"]] autorelease];
[self.navigationController.navigationBar addSubview:bgImageView];
You have to tweak a little based on what other elements you have in your UINavigationBar for your UIImageView to be at the lowest index of the subviews but still above the background. Worked for us.
Good luck.