UISearchBar modifying its frame/bounds when clicked - ios

I'm trying to place a UISearchController within my apps UI. The layout is:
Yellow: a ViewController
Red: another ViewController
Black: a container within the YellowViewController
I want to put the UISearchView of the UISearchController within the black container.
My code is the following:
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsViewController];
UISearchBar* searchBar = self.searchController.searchBar;
searchBar.frame =_searchBarContainer.bounds;
[_searchBarContainer addSubview:searchBar];
[_searchBarContainer layoutIfNeeded];
It places the UISearchBar in the correct place:
But when I select the search field it expands the bar over the container's bounds:
How can I solve that and avoid the size/appearance change when selected?
Note: Tried some options playing with the translatesAutoresizingMaskIntoConstraints and the clipToBounds options with no success. I'm not an expert of iOS UI so I would appreciate an accurate answer. Thanks

According to my research, at each time you select SearchBar, a UISearchController is presented. This UISearchController always try to make searchBar's width equals to UIViewController which is presenting UISearchController.
My solution is when UISearchController makes SearchBar has wrong frame, set SearchBar'frame again. You can try this code below.
#interface ViewController () <UISearchControllerDelegate>
#property (nonatomic, strong) UISearchController* searchController;
#property (weak, nonatomic) IBOutlet UIView *searchBarContainer;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsViewController];
UISearchBar* searchBar = self.searchController.searchBar;
self.searchController.delegate = self;
searchBar.frame =_searchBarContainer.bounds;
[_searchBarContainer addSubview:searchBar];
[_searchBarContainer layoutIfNeeded];
}
- (void)willPresentSearchController:(UISearchController *)searchController {
[searchController.searchBar addObserver:self forKeyPath:#"frame" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
- (void)willDismissSearchController:(UISearchController *)searchController{
[searchController.searchBar removeObserver:self forKeyPath:#"frame"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if (object == self.searchController.searchBar) {
if (!CGSizeEqualToSize(self.searchController.searchBar.frame.size, _searchBarContainer.frame.size)) {
self.searchController.searchBar.superview.clipsToBounds = NO;
self.searchController.searchBar.frame = CGRectMake(0, 0, _searchBarContainer.frame.size.width, _searchBarContainer.frame.size.height);
}
}
}
#end
At least, it works :)
Or
You can create another UIViewController which contains SearchBar after that add it to _searchBarContainer if your case don't have any problem with this.
Use UISearchBar and UITableView instead of UISearchController. It's easier to handle.

I have found useful infos.
There are several methods that are invoked when you tap the UISearchBar.
When some of this method are invoked, the frame of the UISearchBar change his value.
One of these methods try to fill the width equal to UIViewController.
Try to set your frame value inside one of these methods:
searchBarTextDidBeginEditing
searchBarShouldBeginEditing
In this way you override the default value.
Bye

Related

How to make floating view?

What I mean by floating view is custom view that is a subview (or appears to be a subview) of scrollview which scrolls along until it anchors on certain point. Similar behavior would be UITableView's section header. Attached image below
My content view (the view underneath the floating view) is not in tableview layout. Meaning if I use tableview only for the floating view, I have to put my content view inside 1 giant cell or break it to several cells with different layouts. The content view will have a lot of dynamic elements which is why I don't want to put it inside UITableViewCell unless I have to. Can I make floating view programmatically / using autolayout on scrollview?
Using the tableview section header is probably the best solution, you can always easily customise the number of cells or cells themselves to achieve a particular layout.
However if you definitely don’t want to deal with a tableview, this component seems really cool, it's actually is meant to be added to a tableview, but I tested it with the twitter example and you can actually add it to a scrollview, so you don’t need a table view and it will work, give props the guy who made it. GSKStretchyHeaderView
Hope this helps, comment if you have any questions, good luck.
Use KVO to update the floating view's frame.
Here is the sample code written in Objective-C:
// ScrollView.m
// ScrollView is a subclass of UIScrollView
#interface ScrollView ()
#property (nonatomic, strong) UIView *floatingView;
#property (nonatomic) CGRect originalBorderFrame;
#property (nonatomic) CGFloat anchorHeight;
#end
#implementation ScrollView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.floatingView = [UIView new];
self.floatingView.backgroundColor = [UIColor colorWithRed:0.8211 green:0.5 blue:0.5 alpha:1.0];
self.floatingView.frame = CGRectMake(0, 150, frame.size.width, 20);
self.originalBorderFrame = self.floatingView.frame;
[self addSubview:self.floatingView];
self.anchorHeight = 44;
[self addObserver:self forKeyPath:#"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
- (void)dealloc {
[self removeObserver:self forKeyPath:#"contentOffset"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:#"contentOffset"]) {
if (self.contentOffset.y > self.originalBorderFrame.origin.y-self.anchorHeight) {
self.floatingView.frame = CGRectOffset(self.originalBorderFrame, 0, self.contentOffset.y - (self.originalBorderFrame.origin.y-self.anchorHeight));
}
}
}
#end
Here is the capture:

Move UINavigationController's toolbar to the top to lie underneath navigation bar

When you create a UINavigationController, you can reveal its default hidden UIToolbar via setToolbarHidden:animated: (or by checking Shows Toolbar in Interface Builder). This causes a toolbar to appear at the bottom of the screen, and this toolbar persists between pushing and popping of view controllers on the navigation stack. That is exactly what I need, except I need the toolbar to be located at the top of the screen. It appears that's exactly what Apple has done with the iTunes app:
How can one move UINavigationController's toolbar to the top to lie underneath the navigation bar instead of at the bottom?
I've tried to implement the UIToolbarDelegate, override positionForBar:, and return UIBarPosition.TopAttached or UIBarPosition.Top after setting the delegate of self.navigationController?.toolbar to self, but this did not even call the delegate method therefore it didn't change the bar position.
Note that I need the toolbar to be preserved between navigation, so I can't simply add a toolbar to a view controller and position it under the nav bar.
The solution for this problem is a two (and a half) step process:
First you have to add an observer to the toolbars 'center' member.
Second, inside your observeValueForKeyPath:ofObject:change:context:, relocate the toolbar to your target position every time it is moved by somebody (e.g. the navigation controller itself for example, when the device rotates).
I did this in my UINavigationController subclass.
To avoid recursion, I've installed an local flag member 'inToolbarFrameChange'.
The last (half) step was a bit tricky to find out... you've to access the toolbars 'frame' member, to get the observer to be called at all... I guess, the reason for this might be, that 'frame' is implemented as an method inside UIToolbar and the base 'frame' value in UIView is only updated when the UIToolbar method is called ?!?
I did implement this 'frame' access in my overloaded setToolbarHidden:animated: method, which does nothing but to forward the call and to access the toolbars 'frame' value.
#interface MMMasterNavigationController ()
#property (assign, nonatomic) BOOL inToolbarFrameChange;
#end
#implementation MMMasterNavigationController
/*
awakeFromNib
*/
- (void)awakeFromNib {
[super awakeFromNib];
// ... other inits
self.inToolbarFrameChange = NO;
}
/*
viewDidLoad
*/
- (void)viewDidLoad {
[super viewDidLoad];
// 'center' instead of 'frame' from: http://stackoverflow.com/a/17977278/2778898
[self.toolbar addObserver:self
forKeyPath:#"center"
options:NSKeyValueObservingOptionNew
context:0];
}
/*
observeValueForKeyPath:ofObject:change:context:
*/
- (void)observeValueForKeyPath:(NSString *)pKeyPath
ofObject:(id)pObject
change:(NSDictionary<NSString *,id> *)pChange
context:(void *)pContext {
if ([pKeyPath isEqualToString:#"center"]) {
if (!self.inToolbarFrameChange) {
//NSLog(#"%s (0): %#", __PRETTY_FUNCTION__, pChange);
self.inToolbarFrameChange = YES;
CGRect tbFrame = self.toolbar.frame;
// maybe some other values are needed here for you
tbFrame = CGRectMake(0, 0, CGRectGetWidth(tbFrame), CGRectGetHeight(tbFrame));
self.toolbar.frame = tbFrame;
self.inToolbarFrameChange = NO;
}
} else {
[super observeValueForKeyPath:pKeyPath ofObject:pObject change:pChange context:pContext];
}
}
/*
setToolbarHidden:animated:
*/
- (void)setToolbarHidden:(BOOL)pHidden
animated:(BOOL)pAnimated {
FLog;
[super setToolbarHidden:pHidden animated:NO];
// Access the 'frame' member to let to observer fire
CGRect rectTB = self.toolbar.frame;
rectTB = CGRectZero;
}
You may create not UITableViewController but UIViewController. In view of UIViewController place UIToolBar below NavigationBar and UITableView. Delegate all necessary list of UITableView to UIViewController and thats all.
Why should you use UIViewController instead UITableViewController? Because tableView will not have statical positions elements. You should have something that not contains ScrollView. In this situation it is only UIView. Also you may do some hack with UIScrollView of tableView but I think described method is easer.

iOS 7 UITextView vertical alignment

How is that possible that my editable UITextView (placed inside a straightforward UIViewController inside a UISplitView that acts as delegate for the UITextView) is not showing text from the beginning but after something like 6-7 lines?
I didn't set any particular autolayout or something similar, trying to delete text doesn't help (so no hidden chars or something).
I'm using iOS 7 on iPad, in storyboard looks good...
The problem is the same on iOS simulator and real devices. I'm getting mad :P
Here's some code. This is the ViewController viewDidLoad()
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.itemTextField.delegate = self;
self.itemTextField.text = NSLocalizedString(#"NEWITEMPLACEHOLDER", nil);
self.itemTextField.textColor = [UIColor lightGrayColor]; //optional
}
And here are the overridden functions for the UITextView I'm using some code I've found on StackOverflow to simulate a placeholder for the view (the same stuff on iPhone version of the storyboard works fine)...
// UITextView placeholder
- (void)textViewDidBeginEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:NSLocalizedString(#"NEWITEMPLACEHOLDER", nil)]) {
textView.text = #"";
textView.textColor = [UIColor blackColor]; //optional
}
[textView becomeFirstResponder];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:#""]) {
textView.text = NSLocalizedString(#"NEWITEMPLACEHOLDER", nil);
textView.textColor = [UIColor lightGrayColor]; //optional
}
[textView resignFirstResponder];
}
-(void)textViewDidChange:(UITextView *)textView
{
int len = textView.text.length;
charCount.text = [NSString stringWithFormat:#"%#: %i", NSLocalizedString(#"CHARCOUNT", nil),len];
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
return YES;
}
Try to call -sizeToFit after passing the text. This answer could be useful to Vertically align text within a UILabel.
[UPDATE]
I update this answer o make it more readable.
The issue is that from iOS7, container view controllers such as UINavigationController or UITabbarController can change the content insets of scroll views (or views that inherit from it), to avoid content overlapping. This happens only if the scrollview is the main view or the first subviews. To avoid that you should disable this behavior by setting automaticallyAdjustsScrollViewInsets to NO, or overriding this method to return NO.
I got through the same kind of issue.
Solved it by disabling the automatic scrollView insets adjustement :
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")){
self.automaticallyAdjustsScrollViewInsets = NO; // Avoid the top UITextView space, iOS7 (~bug?)
}
This is a fairly common problem, so I would create a simple UITextView subclass, so that you can re-use it and use it in IB.
I would used the contentInset instead, making sure to gracefully handle the case where the contentSize is larger than the bounds of the textView
#interface BSVerticallyCenteredTextView : UITextView
#end
#implementation BSVerticallyCenteredTextView
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self addObserver:self forKeyPath:#"contentSize" options: (NSKeyValueObservingOptionNew) context:NULL];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder])
{
[self addObserver:self forKeyPath:#"contentSize" options: (NSKeyValueObservingOptionNew) context:NULL];
}
return self;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:#"contentSize"])
{
UITextView *tv = object;
CGFloat deadSpace = ([tv bounds].size.height - [tv contentSize].height);
CGFloat inset = MAX(0, deadSpace/2.0);
tv.contentInset = UIEdgeInsetsMake(inset, tv.contentInset.left, inset, tv.contentInset.right);
}
}
- (void)dealloc
{
[self removeObserver:self forKeyPath:#"contentSize"];
}
#end
use -observerForKeyPath with contentSize KeyPath
Look some code at My Blog (don't focus on Thai Language)
http://www.macbaszii.com/2012/10/ios-dev-uitextview-vertical-alignment.html
Inspired by Kiattisak, I've implemented vertical alignment as a category over UITextView so that you can control the vertical alignment of legacy UITextView.
You can find it as a gist here.
I had the same issue with iOS 8.1, and none of these suggestions worked.
What did work was to go into the Storyboard, and drag my UITableView or UITextView so that it was no longer the first subview of my screen's UIView.
http://www.codeproject.com/Tips/852308/Bug-in-XCode-Vertical-Gap-Above-UITableView
It seems to be linked to having a UIView embedded in a UINavigationController.
Bug ? Bug ? Did I say "bug" ...?
;-)
Swift version of Tanguy.G's answer:
if(UIDevice.currentDevice().systemVersion >= "7.0") {
self.automaticallyAdjustsScrollViewInsets = false; // Avoid the top UITextView space, iOS7 (~bug?)
}
Check top content inset of textView in -viewDidLoad:
NSLog(#"NSStringFromUIEdgeInsets(self.itemTextField.contentInset) = %#", NSStringFromUIEdgeInsets(self.itemTextField.contentInset));
Reset it in storyboard if it is not zero

Is it possible to change the navigation bar title outside of viewDidLoad/viewWillAppear?

I'm trying to change the navigation bar title with this statement:
[[self navigationItem] setTitle:myTitle];
It works fine in viewDidLoad and viewWillAppear, but it doesn't work anywhere else. Is what I am trying to do possible? It's a view controller I'm working with.
There is a very simple way to change the title for the current view controller.
self.title = #"New Title";
Calling this on a view controller that is in a navigation controller will result in the title shown in the navigation bar being updated with the new title.
This can be called at any time while the view controller is displayed.
There is no need to dig into the view controller's navigationItem for setting the title.
I know this is old, but I wanted to answer this for future users. I think the main issue that most answers don't cover is that it is important to set the title from the main thread, otherwise there are a handful of cases where it won't get set immediately. For Swift 3.0 you can use code like this:
DispatchQueue.main.async {
self.title = "Example string"
}
It is important to do all UI updates from the main thread. I'm not sure if the original user was setting the title via an asynchronous closure, but this should help anyone who is having difficulties.
It's actually the view controller's title property that the navigationItem will use. The answer above is the simplest and correct way to change the title in the navigation bar.
If you need to customize your navigation bar, the way you do this is to override it in your UIViewController subclass, NOT change it in viewDidAppear: or any other viewWill/Did methods
- (UINavigationItem*)navigationItem
{
UINavigationItem *navigationItem = [super navigationItem];
// customize it further than the default
return navigationItem;
}
In addition, you can have changes in your title update a custom titleView using KVO. You listen for changes in the UIViewController's title property and update the titleView property of your navigationItem. Check this out:
static void *kObjectStateObservingContext = &kObjectStateObservingContext; // outside your #implementation bit
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// other init stuff here...
[self addObserver: self forKeyPath:#"title" options:NSKeyValueObservingOptionNew context: kObjectStateObservingContext];
}
return self;
}
Don't forget to remove the observer:
- (void)dealloc
{
[self removeObserver: self forKeyPath:#"title"];
}
And now we revisit the navigationItem again, where you can create a custom UILabel that will update whenever we change the title, and after that we have to provide a handler implementation for when the title does change:
- (UINavigationItem*)navigationItem
{
UINavigationItem *navigationItem = [super navigationItem];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(roundf((320 - 230)/2), 0, 230, 44)];
titleLabel.font = [UIFont systemFontOfSize: 18];
titleLabel.textColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"topnav-background-text-gradient.png"]]; // you can even draw the font with a gradient!
titleLabel.shadowColor = [UIColor colorWithWhite: 1.0 alpha:0.59];
titleLabel.shadowOffset = CGSizeMake(0, 1.0);
titleLabel.text = self.title;
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textAlignment = UITextAlignmentCenter;
navigationItem.titleView = titleLabel;
return navigationItem;
}
And finally, what to do when self.title actually changes:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ( context == kObjectStateObservingContext ) {
// here we update the text of the titleView
if ([self.navigationItem.titleView isKindOfClass:[UILabel class]]) {
[(UILabel*)self.navigationItem.titleView setText: self.title];
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
And there you go! Obviously a bit more code than you might have thought, so if you're not currently, I recommend to anyone building iOS Apps that you always create a base class view controller for your application, (MyBaseViewController : UIViewController) then subclass that for any other view controllers in your app.
You can set up the the title in viewDidLoad, because the view is not yet visible but instaciated. Same story for viewWillAppear. After the UIElement is visible, you cant change the title without a redraw.
#reid55 you can set navigation title in below method also:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[[self navigationItem] setTitle:myTitle];
}
return self;
}

UITableView headings shown on top of MBProgressHUD

So I have a subclass of UITableViewController that loads some data from the internet and uses MBProgressHUD during the loading process. I use the standard MBProgressHUD initialization.
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = #"Loading";
[HUD show:YES];
This is the result:
.
Is there any way to resolve this issue, or should I just abandon MBProgressHUD?
Thanks!
My solution was pretty simple. Instead of using self's view, I used self's navigationController's view.
HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view addSubview:HUD];
This should work for the OP because his picture shows he's using a UINavigationController. If you don't have a UINavigationController, you might add another view on top of your UITableView, and add the HUD to that. You'll have to write a little extra code to hide/show this extra view.
An unfortunate thing with this simple solution (not counting my idea adding another view mentioned above) means the user can't use the navigation controls while the HUD is showing. For my app, it's not a problem. But if you have a long running operation and the user might want to press Cancel, this will not be a good solution.
It's probably because self.view is a UITableView, which may dynamically add/remove subviews including the headers, which could end up on top of the HUD after you add it as a subview. You should either add the HUD directly to the window, or (for a little more work but perhaps a better result) you could implement a UIViewController subclass which has a plain view containing both the table view and the HUD view. That way you could put the HUD completely on top of the table view.
My solution was:
self.appDelegate = (kmAppDelegate *)[[UIApplication sharedApplication] delegate];
.
.
_progressHUD = [[MBProgressHUD alloc] initWithView:self.appDelegate.window];
.
[self.appDelegate.window addSubview:_progressHUD];
Works like a charm for all scenarios involving the UITableViewController. I hope this helps someone else. Happy Programming :)
Create a category on UITableView that will take your MBProgressHUD and bring it to the front, by doing so it will always appear "on top" and let the user use other controls in your app like a back button if the action is taking to long (for example)
#import "UITableView+MBProgressView.h"
#implementation UITableView (MBProgressView)
- (void)didAddSubview:(UIView *)subview{
for (UIView *view in self.subviews){
if([view isKindOfClass:[MBProgressHUD class]]){
[self bringSubviewToFront:view];
break;
}
}
}
#end
A simple fix would be to give the z-index of the HUD view a large value, ensuring it is placed in front of all the other subviews.
Check out this answer for information on how to edit a UIView's z-index: https://stackoverflow.com/a/4631895/1766720.
I've stepped into a similar problem a few minutes ago and was able to solve it after being pointed to the right direction in a different (and IMHO more elegant) way:
Add the following line at the beginning of your UITableViewController subclass implementation:
#synthesize tableView;
Add the following code to the beginning of your init method of your UITableViewController subclass, like initWithNibName:bundle: (the beginning of viewDidLoad might work as well, although I recommend an init method):
if (!tableView &&
[self.view isKindOfClass:[UITableView class]]) {
tableView = (UITableView *)self.view;
}
self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.tableView.frame = self.view.bounds;
self.tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0);
[self.view addSubview:self.tableView];
Then you don't need to change your code you posted in your question any more. What the above code does is basically seperating the self.tableView from self.view (which was a reference to the same object as self.tableView before, but now is a UIView containing the table view as one might expect).
I've Just solved that issue manually , it has been 2 years since Chris Ballinger asked but maybe someone get used of what is going on here.
In UITableViewController i execute an HTTP method in viewDidLoad , which is running in background so the table view is loaded while the progress is shown causing that miss.
i added a false flag which is changed to yes in viewDidLoad, And in viewDidAppear something like that can solve that problem.
-(void) viewDidAppear:(BOOL)animated{
if (flag) {
[self requestSomeData];
}
flag = YES;
[super viewDidAppear:animated];
}
I had the same problem and decided to solve this by changing my UITableViewController to a plain UIViewController that has a UITableView as a subview (similar to what jtbandes proposed as an alternative approach in his accepted answer). The advantage of this solution is that the UI of the navigation controller isn't blocked, i.e. users can simply leave the ViewController in case they don't want to waiting any longer for your timely operation to finish.
You need to do the following changes:
Header file:
#interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
- (id)initWithStyle:(UITableViewStyle)style;
#end
Implementation file:
#interface YourViewController ()
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, retain) MBProgressHUD *hud;
#end
#implementation YourViewController
#pragma mark -
#pragma mark Initialization & Memory Management
- (id)initWithStyle:(UITableViewStyle)style;
{
self = [super init];
if (self) {
// create and configure the table view
_tableView = [[UITableView alloc] initWithFrame:CGRectNull style:style];
_tableView.delegate = self;
_tableView.dataSource = self;
}
return self;
}
- (void)dealloc
{
self.tableView = nil;
self.hud = nil;
[super dealloc];
}
#pragma mark -
#pragma mark View lifecycle
- (void)loadView {
CGRect frame = [self boundsFittingAvailableScreenSpace];
self.view = [[[UIView alloc] initWithFrame:frame] autorelease];
// add UI elements
self.tableView.frame = self.view.bounds;
[self.view addSubview:self.tableView];
}
- (void)viewWillDisappear:(BOOL)animated
{
// optionally
[self cancelWhateverYouWereWaitingFor];
[self.hud hide:animated];
}
The method -(CGRect)boundsFittingAvailableScreenSpace is part of my UIViewController+FittingBounds category. You can find its implementation here: https://gist.github.com/Tafkadasoh/5206130.
In .h
#import "AppDelegate.h"
#interface ViewController : UITableViewController
{
MBProgressHUD *progressHUD;
ASAppDelegate *appDelegate;
}
In .m
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
appDelegate = (ASAppDelegate *) [UIApplication sharedApplication].delegate;
progressHUD = [MBProgressHUD showHUDAddedTo:appDelegate.window animated:YES];
progressHUD.labelText = #"Syncing To Sever";
[appDelegate.window addSubview:progressHUD];
This should work.
[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
And to remove you can try
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];

Resources