iOS Developement: App Crashes on Reopen - objective-c

My app is almost finish but when i am testing it, on first use everything is working well and smooth. But, after closing it from the home button and reopen it when i click my back it;s crashing.
in my back button i only have this code:
[view1 removeFromSuperview];
[view2 removeFromSuperview];
[self view3];
what could be the problem??

Why are you removing views from superview when you push the back button.
also what do you think will happen by saying
[self view3]; ?
I would suggest if you've added views in the viewDidLoad method
that you should remove them using the viewdidUnload method and not in the back button method. As if you try an remove a view that has already been release, your app will crash.
If you're attempting something different then you need to show more code.

Related

UIMenuController Editing Menu in UIWebView only appears second time

I am finding that in my app in iOS 9, when I long press in a UIWebView, the editing menu that normally appears, only appears the second (and following) times that I long press. The first time I long press in any particular webview no menu at all shows, although the selection handles do appear. The second time I long press in any partiular webview, it behaves as expected.
Another strange symptom is that occasionally (but not every time) as the menu appears, something quickly animates sliding of towards the left of the screen, originating from the menu, but it is too fast to see what it is. It happens even when the edit menu appears as it should. I expect this is related to the issue.
I have only tested in the simulator because I haven't installed iOS 9 on a device yet.
In iOS 8 the same menu works as expected.
Another developer gave me a work around, which may work when you have only one UIWebVeiw on screen. Put this in viewDidAppear (thanks Chen Xian'an):
[[myWebView.scrollView.subviews firstObject] becomeFirstResponder];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self becomeFirstResponder];
}];
However, since I have more than one webView it is not an ideal solution for me. And if I apply it to each webview it only works on the last one I apply it to.
This appears to be a bug, and hopefully Apple will fix it soon, in the meantime, does anyone have any bright ideas as to how I could make this work for more than one webView?
I tried in this way, and I succeeded.
First
You must custom UIWebView and write
- (BOOL)canBecomeFirstResponder {
return YES;
}
Second
You must call this methods before handle your long press
[yourWebView becomeFirstResponder];
I hope it would help..
In my case the problem that was the UIWindow where the UIWebView was apparently not the key window. What i did to solve it was to add a call to [webView.window makeKeyAndVisible] at the webViewDidFinishLoad method.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// Fix
[webView.window makeKeyAndVisible];
}

UIBarButtonItem sent action works on iOS 6 but not iOS 5

I am going to tear my hair out because I cannot think of a logical reason why this occurs on 5 but not 6. So basically, I have a view presented in modal fashion with a navigation bar and a Cancel button (UIBarButtonItem - no custom anything on it, just a standard button) in the navigation bar. When this Cancel button is tapped, I want the modal view to disappear. This works just fine in iOS 6. But for iOS 5 it refuses to work for 2 out of 3 places I have it in my code. What's odd to me is that it works on one but not the other two.
Using storyboards, I right click the button, click on "selector" under Sent Actions, and drag over to the appropriate IBAction method in my view controller's .h file. The link is successfully confirmed with the little blinking animation in Xcode. When I run the app on iOS 6 (simulator or device doesn't matter), the method is successfully executed upon button tap and my modal view dismissed. However, on iOS 5, the method is never even called (I set breakpoints inside the method to see if they would be hit). I've even tried switching the argument in my IBAction method from id to UIBarButtonItem *. No cigar, though.
I've also tried programmatically (in viewDidLoad) setting the cancel button's action to a selector. I've even set the target to the VC. No cigar again. Here is a screenshots of my current setup:
Please note the IBAction methods.
Is there some magical clause in the documentation that I missed? Something awfully special I need to do in order to get it to work in iOS 5? It sure seems like a bug to me, but I'm still fairly new to this stuff so what do I know.
I am using Xcode 4.5.2 and storyboards, and targeting iOS 5 and iOS 6 for the release.
Your help is appreciated, thank you.
I think there may be problem of using GestureRecognizer please comment that code and try it...
I added a separate UIView that resides under my textfields and button and below the navigation bar/title. I added the tap gesture to that programmatically, and that seems to recognize both my tap and the cancel button's action. I still would like to know why the tap gesture swallows up the UIBarButtonItem's action if the gesture is on the root view. This question helped me figure this out. Thanks.
you can exclude view/control from gesture recognizer using following delegate method.
// UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// exclude your view from gesture recognizer
if(yourView == touch.view)
{
return NO;
}
//
return YES;
}

Getting viewDidLoad to be called when using popViewControllerAnimated

I'm using a UINavigationController to navigate between classes. When I press a button on the first view to send me to the second one, everythin works fine. But when I wan't to return from the second, to the first view, the viewDidLoad method isn't being called, and I really need that to happen.
According to this post, I should somehow set my view to nil but I'm not sure where or how to do that. This is the code that I'm using to return to the first view:
NewSongController *nsContr = [[NewSongController alloc] initWithNibName:#"mNSController" bundle:nil];
[self.navigationController popViewControllerAnimated:YES];
[nsContr release];
Your code is not correct.
You don't need to instantiate your first controller in order to pop to it. It already exists.
viewDidLoad will only run when you load the viewController for the first time (i.e. when you push to it). When you push to other controllers they are put onto a stack (imagine a stack of cards). When you push another card onto the stack the cards beneath it are already there.
When you pop it is like removing a card from the stack. But the card underneath is already there so it doesn't need to load again. All it does is run viewWillAppear.
All you need to do to pop back is...
[self.navigationController popViewControllerAnimated:YES];
That's it.
Remove the stuff about NewSongController (if that is what you are trying to go back to).
Then in the NewSongController function - (void)viewWillAppear:animated; put the code you want to run when you get back to it.
Hope that helps.
Your first view is loaded and is pushed onto the navigation stack. Dont try to mess with whats on the stack without fully understanding how setting the view to nil will affect the behavior.
Whatever you do on viewDidLoad, doing it in viewWillAppear or viewDidAppear will give you the result you want.
The viewDidLoad wouldn't appear because it already exists in the navigation stack. Since you are going back in the stack you would want to have the code that you want to trigger in viewWillAppear or viewDidAppear which is executed when popping from one viewcontroller to the one below it.

iOS 5.1 + UISplitViewController in PortraitMode + UIActionSheet in MasterController = Assertion failure

I have an app based on a UISplitViewController that shows an ActionSheet in the MasterViewController of the Split. Before iOS 5.1, I had no problems presenting the action sheet in the popover presented by the split, but now, apparently there is something wrong with the new "slide-in" way to show the MasterController.
The thing is that when I'm trying to present the ActionSheet, using any [actionSheet show..] method, the app crashes with the following error (The exact Assertion is the following).
*** Assertion failure in -[UIActionSheet presentSheetInPopoverView:], /SourceCache/UIKit_Sim/UIKit-1914.84/UIActionSheet.m:1816
sharedlibrary apply-load-rules all
Error in re-setting breakpoint 1:
Catchpoint 2 (throw)Error in re-setting breakpoint 1:
Error in re-setting breakpoint 1:
Current language: auto; currently objective-c
I google this for a while, but no substantial answers.. some people say it can be a bug in the
new SplitViewController...
Ideas?
Thank you in advance!
UPDATE: I posted a possible generic workaround, check it out. If it works for you, leave a comment.... If its ok, I will mark it as correct in a couple of days
Based on the above, and with massive respect to the Apple engineer who helped me at WWDC, here is the solution which not only works around this bug, but also points the popover at the right button.
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
{
[actionSheet showFromBarButtonItem:self.actionSheetBarButtonItem animated:YES];
}
else
{
CGRect windowsRect = [self.navigationController.toolbar convertRect:self.actionSheetBarButtonItem.customView.frame toView:self.view.window];
[actionSheet showFromRect:windowsRect inView:self.view.window animated:YES];
}
I have this same problem too.
One workaround which prevents the crash at least is to show your UIActionSheet like this:
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
[self.actionSheet showFromBarButtonItem:sender animated:YES];
} else {
[self.actionSheet showInView:self.view.window];
}
So in portrait mode, the action sheet is displayed in the center of the window. Not ideal, but at least it doesn't crash. And when in landscape mode, it behaves as normal.
Just as omz commented, it seems this issue has been solved in iOS 5.1.1 by apple.
So I decide to just add it to known issue section of change log for my app, and the workaround is to suggest the users to upgrade to iOS 5.1.1.
Another option to keep the popover affect of pointing at a particular option, you can actually do the following:
1. Create your own UIPopover
2. Create your own UIViewController inside of the UIPopover.
3. Display the UIActionSheet inside the newly created UIViewController.
4. SetPopoverContentSize from the UIActionSheet's Size.
5. Lastly, Wire your UIActionsheet's Clicked method to dismiss the popover.
Takes a little more code, but gives you the same functionality you had before for the most part, and has a cool little slide-in effect for the UIActionsheet.
I think the following is a generic solution based on Tap Form's answer:
CGRect windowsRect = [actionSheetContainerView convertRect:viewToPresentActionSheet.frame toView:actionSheetContainer.window];
[actionSheet showFromRect:windowsRect inView:actionSheetContainer.window animated:YES];
This will resent the actionSheet in the window, but pointing the right direction

Odd behavior when showing UIPopoverController

In my iPad app, I save the state (visible/not visible) of a popover. So, during the launch of the app I initialize the UIPopoverController and tell it to show itself by using presentPopoverFromBarButtonItem:permittedArrowDirections:animated:. For the first argument (UIBarButtonItem), I use self.navigationItem.rightBarButtonItem. However, the popover keeps showing up on the left side of the screen (and not underneath the targeted button).
After the app is launched, the behavior is as expected. Any suggestions how to solve this?
For your information, I initialize the rightBarButtonItem and assign it to the navigationItem in the viewDidLoad method and before asking the popover to present itself. I have tried to call the popover in viewWillAppear and viewDidLoad, but the effect is the same.
My best alternative is to use presentPopoverFromRect:inView:permittedArrowDirections:animated: instead and "guess" the position depending on the orientation of the device.
Update: when I rotate the iPad, the popover does jump to the correct position. It seems that the barButtonItem's position is only determined at the last minute and after I ask my popover to present itself.
In situations like these where timing appears to be important I found that the trick of postponing an action until the next iteration of the run loop helps. If developing for iOS 4.0+, this can be easily achieved with GDC:
// call from viewDidAppear:
dispatch_async(dispatch_get_main_queue(), ^{
// call presentPopoverFromBarButtonItem:permittedArrowDirections:animated: here
});