UINavigation PushViewController Doesn't Display Next View, But Runs The Code - ios

The problem, My home screen is wrapped in a UINavigationController, when I push to the next controller it's fine, but then when I use the left swipe to go back to the home screen then click on the button to take me to the next controller sometimes it works fine about 60% other times it just hangs there. I can see the code executing in my logs as if the view controller has been presented but it's not on screen...
So at this point the whole UI is unresponsive, the only thing I can do is swipe from Left to Right like I want to go back to another page, but this is where it gets funky, the screen that I was trying to display then slides in view from the right side of the screen.
When I let go it reloads the home view, then the app works as designed.
I have no idea whats going on with this thing... Below is my code for presenting the next view:
NextViewController *nextViewController = (NextViewController*)[self.storyboard instantiateViewControllerWithIdentifier:#"NextViewController"];
nextViewController.nameString = [[self.topArray objectAtIndex:[indexPath row]] objectForKey:#"Name"];
nextViewController.championMCID = [[self.topArray objectAtIndex:[indexPath row]] objectForKey:#"UserId"];
[self.navigationController pushViewController:nextViewController animated:YES];
When I get to the next screen because i'm hiding the navigationbar, I am setting the following:
[[self navigationController]setNavigationBarHidden:YES animated:NO];
self.navigationController.interactivePopGestureRecognizer.delegate = self;
And that's it, not quite sure what's going on but any help would be great help thanks.

I integrated a left side menu, that operates as a settings screen, and I believe that the:
self.navigationController.interactivePopGestureRecognizer.delegate = self;
And that left side menu were clashing, when I say clashing I mean, when I pop the next view controller, I believe somewhere in the stack that the views got tangled up. So when I push to another view, the app doesn't know rather to use the left side menu or to use the navigation controller without the left side menu...
So instead of allowing the:
self.navigationController.interactivePopGestureRecognizer.delegate = self;
I decide to place this code in my viewwillappear method:
self.navigationController.interactivePopGestureRecognizer.delegate = self;
NSUInteger viewControllerCount = self.navigationController.viewControllers.count;
NSLog(#"viewControllerCount %ld", viewControllerCount);
if (viewControllerCount == 1)
{
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
else
{
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
I placed this code in the initial navigation controller so whenever I push, the left side menu will be on every screen within the app, and then I implemented a back button on each screen so that I can pop the views instead of sliding left, I didn't want to implement the UINAVIGATIONBAR at the top because I need that small piece of screen as well to display everything haha...
I hope this helps anyone in the future that may have the same issues, good luck, happy coding.

I had this issue too and what I noticed was that my current view controller was not embedded in a UINavigation controller so on using navigationController?.pushViewController(viewController, animated: true) my current navigationController was null

Related

Blank screen before and after the UIWebview load and next view load iOS Objective C

I have two view controllers. In first view controller, I click a button and a webview loads. Before loading web view, it shows a black screen and it goes immediately and the webviews load. Again, when I go from my webview to another view controller, I see the same black screen comes and goes immediately.
PS : This code is not written by me, and it's a little messy so I am not able to paste code here.
Please let me know if you can think of any proper reasoning why its happening and how can I resolve it?
Is there any way i can check for number of view controllers in the stack? Because sometimes instead of black screen it shows some previously loaded screen
This is the code used to remove all the view controller from stack -
UIViewController *vc = self.presentingViewController;
while (vc.presentingViewController) {
vc = vc.presentingViewController;
}
[vc dismissViewControllerAnimated:YES completion:nil];
But still i can see some random screen from the app, comes up instead of black screen before my webview loads.
Any suggestions are welcomed. Thanks!!
Set in InterfaceBuilder or code white background color for UIWebView.
This code may help you:
- (void)viewDidLoad {
[super viewDidLoad];
webViewInstance.opaque = NO;
webViewInstance.backgroundColor = [UIColor clearColor];
//your remaining code here
}

How can I assign a pointer to the keyboard before I have assigned first responder

I am trying to create a user interface enabling users to switch between the keyboard and other menus when using a chat application.
On a click of the textField bar I want to raise either the keyboard or a collection view.
The problem occurs when I click the 'menu' button. I want the textField bar to raise revealing my menu view. Then, on a click on the keyboard button, instantly switch to the keyboard, rather than having it slide up from the bottom. This means I need to have the keyboard already loaded and hidden but in the background of the app.
Currently though the earliest I am managing to assign a variable to the keyboard is in the keyboardDidShow function.
-(void) keyboardDidShow: (NSNotification *) notification {
// Get the window the keyboard is a subview of
_window = [UIApplication sharedApplication].windows.lastObject;
_keyboard = _window.subviews[0];
}
This means that after it has been loaded once I can hide and reveal it, but I don't want it visible when it is loading this first time.
To achieve this using alternate means I have tried adding my extra views as subviews of the UIWindow the keyboard is created in:
[_window addSubview:_menuView];
[_window addSubview:_gamesView];
[_window addSubview:_stickerView];
[self hideSpecificView];
Unfortunately I keep coming across the same problem, until I have loaded the keyboard once it needs to fully load before I can get a pointer to it to hide it.
Here is a picture of my toolBar incase I am not being clear:
On clicking the menu icon or the stickers icon I want the bar to raise with a collection view. If I then click the textfield, with these views visible, I want to hide the visible view to immediately show the keyboard behind.
I have also tried experimenting with keyboardWillShow but as the window hasn't been loaded in front our screen I can't get a pointer to the keyboard to hide it before it loads.
An example of what I am after can be found many chat apps (facebook messenger, LINE, Kakao Talk)
Any help would be greatly appreciated
Although the way I came up with isn't perfect it works almost perfectly so hopefully this might help people in the future. If anyone else has solved it differently please post as it would be interesting to know how you did it.
I started by adding a class variable to a UIWindow in my header file and then setting off a timer to ping just after the keyboard will show method finishes. After this method has finished the keyboard has been created, just, and so I allocate it and hide it.
-(void) keyboardWillShow: (NSNotification *) notification {
// More keyboard code
_window = [UIApplication sharedApplication].windows.lastObject;
[NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:#selector(allocateKeyboard)
userInfo:nil
repeats:NO];
}
- (void)allocateKeyboard {
if (!_keyboard) {
_keyboard = _window.subviews[0];
}
_keyboard.hidden = YES;
[self setViewForButtonType];
}
I have already previously added my other views, hidden them and constrained them to the bottom of the main view, this means that when the keyboard rises they do too.
- (void)viewDidLoad {
[self.view addSubview:_menuView];
[self.view addSubview:_gamesView];
[self.view addSubview:_stickerView];
}
...
- (void)hideViews {
_keyboard.hidden = YES;
_menuView.hidden = YES;
_gamesView.hidden = YES;
_stickerView.hidden = YES;
}
When buttons get pressed I simple then unhide the view that I want to see and hide the rest of the views.
When I say that this method doesn't work perfectly it is because if you load view main view and then click a button before the keyboard has loaded for the first time then you get a quick glimpse of the keyboard before the view appears over the top. This though only happens the first time and only if they don't click in the text field first.
Anyway, I found this was the best way of making views look like they are in front of the keyboard. Obviously my code was a lot longer and more complex (too long for here) but this is the gist of the method I used to solve it. Comment if you have any queries and I hope this helps.

Display a UITableView in a Split View Controller using code

I have Two different UITableView with two Navigation Controller.
I want to display one of them after touching a UIButton in first Table.
In iPhone I use following code
SecondNavigationController second = [SecondNavigationController new];
[self presentModalViewController:second animated:YES];
Note that first is first TableViewController; And second navigation controller it self initiate a UITableView and display it using following code in it's ViewDidLoad method.
SecondTableViewController *root = [SecondTableViewController new];
[self pushViewController:root animated:NO];
Note that first TableView uses application root view controller in iPhone to display it!
And it perfectly works.
In iPad, on the other hand, I use a splitViewController which shows first table view on the left side screen.
I want to show second TableView in the left side too. But above code is not working perfectly. It covers all of iPad screen.
How can I show second UITableView
You need a conditional check which does (pseudo code):
If iPhone
Run current logic
Else
Create a second view controller and push to self.navigationController

UINavigationBar : repaint?

I'm facing a problem I don't understand.
In my main view, I have a button heading to another view. Everything is embedded in a NavigationController.
I successfully changed the background image of my NavigationBar in my main view. But when I click on the button to display my other view, my NavigationBar's isn't repainted although I'm using this code :
- (IBAction) toOtherView : (id) sender
{
if(!otherView) otherView = [[OtherViewController alloc] initWithNibName:#"OtherViewController" bundle:nil];
[self.navigationController pushViewController:otherView animated:NO];
}
However, I also have a Dark Info button on my main view (I choosed the default Utility Application at first). It flips to another view and when I come back to my main view, the NavigationBar image has been changed. So I guess it's a problem of repaint. But what can I do here ?
Thanks a lot for your advices.

How to handle backBarButtonItem pressed?

I have almost done this in all the application but I have 3 views stacked in navigationController and I need to jump from the third view to the first view.
As I understand I can do this via viewWillDisappear only. But if I try this "jump" I will get the navigationController panel from the second View which with a navigation buttons which cause exceptions/errors.
P.S. Do not advice me to make leftBarButtonitem looking like backBarButtonItem. It is too difficult and I don't know where to find an appropriate image for it.
To my knowledge, you have no choice but to provide your own UIBarButtonItem. You are not permitted from interrupting how UINavigationController works by default. That is, you cannot override the behavior of the back button. You must provide a custom bar button item and set it as the navigation item's left bar button item.
(As a side note, the sort of behavior you're looking for may be an indication of a poor navigation pattern. Back buttons should almost always back out of a navigation hierarchy sequentially.)
Let's say in navigation order your views stacked like top -> 3 -> 2 -> 1 . When you are in this position you can have a flag in your application delegate that shows you will doublePop when backButton pressed as below: ( You are doing this whenever third view appears in the order you mentioned)
MyApplicationDelegate * del = [[UIApplication sharedApplication]delegate];
del.doublePopEnabled = YES;
[del release];
In view 2 :
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
MyApplicationDelegate * del = [[UIApplication sharedApplication]delegate];
if(del.doublePopEnabled){
//Asssuming you have a reference to your navigationController in your view 2
del.doublePopEnabled = NO;
[del.release]
//Use animated as no if you don't want user to see doublePopping.
self.navigationController popViewControllerAnimated:NO];
}
}
Hope it helps.

Resources