Moving the position of the back item in a UINavigationBar iPhone - iphone

Trying to move the position of the back item on the UINavigationBar by getting a handle to the backbutton however I only seem to be able to make it disappear rather than do anything with it
I have the following in viewDidLoad
self.navigationItem.leftBarButtonItem.title =#"Testing";
self.navigationItem.backBarButtonItem.title= #"1234";
They do not work however
self.navigationItem.hidesBackButton = YES;
Works as you would expect, looking through the documentation it looks like higher up the backItem might be readonly is this the case?
self.navigationController.navigationBar.backItem; // readonly
Any pointers on how to move this in approx 30 pixels much appreciated!

I don't believe this is possible. However, you can define a custom button (with back functionality) and place it wherever you want on the nav bar. Then simply hide the back button

Related

iPhone - how may I hide a view and let it's space be used by other view (like android visibility = GONE)

Do you know a simple (or not simple) way to hide a view (or anything like a view) and let the other views of the screen use the place left blank ? And make the opposite when showing back that view. Something like Android Visibility = GONE for layers.
As far as I know, using setHidden=YES only hide the view from the screen but does not rearrange anything around it.
On Android, there are 2 hidding method. One like visibility = HIDE, and the other : visibility = GONE.
Let's say we have 3 views each with an height of 100px.
On Android :
If you set view2 visibility = HIDE, it just hides, and nothing else happens.
If you set view2 visibilty = GONE, the view2 hides from the screen and the view3 automaticaly takes the place freed by view2.
That's what I'm looking to on the iPhone.
I imagine there no auto way to do this but do you know any snippet or code making this possible ?
Thank you
There's no auto-tiling in iOS, so the only way to do this is to resize each of the views to how you want them to be yourself, perhaps by implementing layoutSubviews on their superview.

Re-add a UIButton

I'm creating a simple matching game for kids for iPad. All images are drawn on buttons.
When a matching pair is found,
[matchedBtn1 removeFromSuperview];1
[matchedBtn2 removeFromSuperview];
Now, I'm creating a reset function which allows player to reset the once he/she is done.
Question is how do I re-add the UIButtons</code>?
Tried this,
[self addSubview:matchBtn1];
But the program crashes once reset button is clicked and gives this warning for every button I addSubview to
"viewController" may not respond to "-addSubview".
Many thanks in advance for your help. :)
try :
[self.view addSubview:matchBtn1];
I think you should be trying to add them to the view of the controller, not the view controller itself.
[[viewController view] addSubView:matchBtn1]; 
Also make sure you have kept a retained copy of matchBtn1 somewhere in your classes as it will have been released when you removed the subviews.
Instead of adding and removing them, create a set of transparent views over the buttons and when you want to remove them, change the color of those views so that the buttons are hidden. That way if you want to reset the screen, you just have to reset all those views to transparent. You may have to set the cover views to intercept touches too, so the user doesn't click hidden buttons.

Show a UINavigationBar back button without pushing a view controller

In the iPad's Photos app, when you tap an album the stack of pictures expands to fill the screen - you're in the same view, it's just rearranged the grid a little. But at the top, a left-arrow-style Back button appears, as if pushViewController had been used - except it fades in neatly, rather than sliding in. When you tap that, it fades out again, rather than sliding out.
Is there a way to replicate this behaviour? I've tried a few options so far, and might just be missing something. What I've tried:
Setting self.navigationItem's leftBarButtonItem works, but gives me a square button rather than an angled Back-style one - there are a few hacks online to make this work, such as using pictures for the button, but I'd rather only use them if there's definitely no "official" way to do this.
Setting self.navigationItem.backBarButtonItem - this is generally used to customise the back button when a view controller is pushed, so it has no effect.
[self.navigationController.navigationBar setItems::] - this works, although it gives me the sliding animation rather than fading. As a result, I use animated:NO to make it just appear. Downside: when tapping Back, you do get the sliding out animation, which looks weird because the rest of the UI stays still.
Has anyone managed to replicate this effect?
Thanks in advance!
Your first approach is probably the best.
It doesn't have to be super-hacky, you can use a normal UIButton and customize it to look like a back-button using backgroundImageForState: and titleForState: (etc.), then set the UIButton object as the customView of your UIBarButtonItem.
Many apps these days customize the look & feel of the buttons anyway, so using a custom background image is quite normal. If you use resizableImageWithCapInsets: (or stretchableImageWithLeftCapWidth:topCapHeight: if you need to support iOS earlier than 5.0) then the button can still stretch to fit whatever text goes inside, and as it's a normal UIButton the text is localizable, etc. I don't consider this approach to be hacky, it is a perfectly sensible way to get around the limited functionality of UIBarButtonItem objects.
Better late than never.
To show a back button without pushing a view controller, use pushNavigationItem:animated: and popNavigationItemAnimated: on UINavigationBar. These result in the standard slide animation and creation of a back button. However, there is no way to ensure your content animation runs for the same time as the bar animation other than making an educated guess at the duration.
Since iOS 7 there is a better API for achieving this effect, where you still push and pop view controllers but you provide a custom transition animation through navigationController:animationControllerForOperation:fromViewController:toViewController: from UINavigationControllerDelegate. This allows the animations between the bar and content to be perfectly coordinated.
Finally, if your content before and after is managed by UICollectionViewController, you can use useLayoutToLayoutNavigationTransitions, which is designed for use-cases like Photos.

refreshing my applicationData ( actually my Title )

I seem to be having a problem with the titles in my application.
Let me describe what is happening here.
1) starts out good with the correct image
http://img262.imageshack.us/img262/5808/picture15b.png
2) still good after clicking a cell
http://img31.imageshack.us/img31/4440/picture13dvg.png
3) after hitting the backbutton previous title remains and the last one is gone
http://img150.imageshack.us/img150/5689/picture14ltq.png
4) however after scrolling up and down fast enough the correct view appears again
http://img262.imageshack.us/img262/5808/picture15b.png
As you can see in the images above I'm using a UITableview however I'm NOT using the navigationItem title , I'm using a UILabel ( called title ).
When I click on my cells and scroll through my application everything is fine however when I click my backbutton, which is also not a standard backbutton from the tableview, but a UIBarbuttonItem it just pops the last view (and does some other stuff too)( the button below as seen in my imagelinks).
-(void)back_clicked:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
....
}
It appears that my Titles do not refresh when I press the back button(which makes sense I guess since i do not have some sort of a refresh function ).
I concluded this because when I scroll down really fast my original title comes back.
I noticed but could be wrong , bear with me here , that reloadData applies mostly to table ,cell constructing and such so I assume this is not the one I'm looking for.
So is there some sort of refresh function I can use ?
I would really like some suggestions ;)
thnx all for reading
If when you h it the back button you are coming back to another viewController i would suggest looking at the method viewWillAppear from UIViewController, you can override this method and call it before you go back, in the method implementation you can set the correct title ...reference http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewWillAppear:
How are you inserting the UILabel that you use as a title?
Like this: [self.navigationController.navigationBar.titleView = < label >];
or more like this: [< top window > addSubview: < label >];
I've never had any problems with custom title views using the first method.

How can I dynamically hide a button from a view?

I would like to dynamically hide a button in one of my views depending on a certain condition.
I tried adding some code to the view controller's -viewWillAppear method, to make the button hidden before displaying the actual view, but I still don't know how to do that.
I have a reference to the button through an IBOutlet, but I'm not sure how to move forward from here. For reference, this is a UIBarButtonItem instance.
If you're trying to hide a UIBarButtonItem, you'll actually have to modify the contents of the parent bar. If it's a UIToolBar, you'll need to set the bar's items array to an array that doesn't include your item.
NSMutableArray *items = [[myToolbar.items mutableCopy] autorelease];
[items removeObject: myButton];
myToolbar.items = items;
Set the bar item to nil.
For example:
self.navigationItem.leftBarButtonItem = nil;
So I tried Ben's winning approach but in the end I found it to be wrong for my purposes - though I'm sure it depends upon what you're trying to do. I was trying to show a nav bar button under certain conditions only and then hide it as soon as the condition was no longer met (in my case it's a "Done" button used to hide the keyboard associated with a UITextView. It should only be displayed when the user is typing in the text view). My steps were as follows:
I added a UIBarButtonItem as a
property in my UIViewController
class. I instantiate it in the
initWithNibName method.
I assigned the UIBarButtonItem property as the
rightBarButtonItem in the nav bar as
soon as the user starts typing in
the text view.
I set the UIBarButtonItem property
to nil when the user is done typing.
It's working like a charm. I'm adding some code samples below.
First to instantiate the button in my view controller init method:
barButtonItemDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done:)];
Then I set it as the right bar button in the delegate method that is called as soon as the user starts to edit the text view:
self.navigationItem.rightBarButtonItem=[self barButtonItemDone];
Finally, when the button itself is clicked, a method called "done" is called and I just set the rightBarButtonItem to nil inside that method:
self.navigationItem.rightBarButtonItem=nil;
If all that one is trying to hide is the back button in the navigation bar, there is an easier way:
self.navigationItem.hidesBackButton = YES;
Quote from developer documentation:
hidesBackButton
A Boolean value that determines whether the back button is hidden.
#property(nonatomic, assign) BOOL hidesBackButton
Discussion
YES if the back button is hidden when this navigation item is the top
item; otherwise, NO. The default value
is NO.
Availability
Available in iPhone OS 2.0 and later.
This is a bit of a hack, but it works in my case (and it properly handles dynamic spacing):
To hide:
myButton.width = 0.1;
To show:
myButton.width = 0.0;
A width of 0.0 is "auto width", and with a width of 0.1, the button totally disappears (not even a "sliver" of a button, though I haven't tried this on a retina display).
Another hacky solution:
myButton.customView = [[UIView alloc] init];
The best solution to this is less technical. All you need to do is create your normal navigation bar (top) or toolbar (bottom), but without the optional button. Then create another identical, but shorter bar which you then place at the part you want the optional button and create your optional button on this second shorter bar.
Now you can call hidden = YES on the whole additional bar.
The bars seamlessly overlap for me, your mileage may vary.
This answer is regarding text-based UIBarButtonItems, however, the same concept could be applied to other types of buttons as well. Note that this will allow one to both hide and show the item again. Many of the answers above (those setting the button's value to nil, for example, do not allow the button to be re-shown if that's desired).
TL;DR:
if (shouldShowMyBarButtonItem) {
self.myBarButtonItem.title = nil;
self.myBarButtonItem.action = nil;
} else if (!shouldShowMyBarButtonItem) {
self.myBarButtonItem.title = #"Title";
self.myBarButtonItem.action = #selector(mySelector:);
}
The long version:
The UIBarButtonItem I was trying to hide is in a UIToolbar, not a UINavigationBar so all the suggestions that access the left (or right) barButtonItem properties on the navigation item don't work for me. Also, as stated above, I wished to re-show the button when circumstances change.
Michael's suggestion came closest to working, however, with iOS 7 at least, there was still a very small sliver of the button displayed that was tappable. In my app, tapping the item when it's not supposed to be available was unacceptable. The above code both hides and, crucially, deactivates the button.
I call the above code in a private refresh method, which is called when a user event occurs.
This is what I did for button items that weren't part of the navigation bar (where Blank.png is a blank image I created that's the same size of the image it replaces):
theButton.enabled = NO;
theButton.image = [UIImage imageNamed: #"Blank.png"];
Ben's answer is technically correct, though when I try it on my custom UIToolbar, the items space out in a way that I don't like, because I use UIBarButtonSystemItemFlexibleSpace items.
If you want your other items to stay in the same place, you'll either have to set your flexible spaces to fixed spaces, or try what I did:
[filterBarButton.customView setHidden:YES];
note: this only works if your UIBarButtonItem uses custom views.
If you add a UIButton to the UIBarButtonItem rather than just use the UIBarButtonItem.
You can then assign UIButton.hidden to TRUE or YES and it (and the UIBarButtonItem) will not be visible or active.
Hope that helps.
Just set the button's hidden property to true:
myButton.hidden = YES;