iPhone: How to show UIWebview on top of UITableView? - iphone

In my Universal app which supports IOS4 and later, I have a UINavigationController and pushing UITableViews using UITableViewController.
Some pages may need to show some messages in HTML so I wanna use WebView. So I imagined like this;
When a new tableview is pushed I will check if it needs to show any messages if yes the new window will open up with a webview on top of the tableview covering maybe %80 of the screen and the tableview is disabled at that moment, when user is done reading the webview they will close it and tableview will be get activated again. Also there will be a message icon on the navigation bar to re-open and re-read the messages again.
How can I do this any ideas?

present the webview modally when the tableview appears:
create your viewcontroller (that has a webview):
UIViewController *webUIViewController = [[UIViewController alloc] init];
locate the navigation controller:
UINavigationController *myNavController = [self navigationController];
present your webview modally:
[myNavController presentModalViewController:webUIViewController animated:YES];
I'd probably only do this for web documents stored locally in the apps bundle though - as you want the user to get feedback of any network loading and what if they have no internet access?

you can use [[cell contantView] addSubview:aWebView].
For instance, you have a boolean : iMustShowAWebView
in cellforrowatindexpath
if (iMustShowAWebView) {
[[cell contantView] addSubview:aWebView]
}
in heighForRowAtIndexPath
if (iMustShowAWebView)
return 44;
else
return 0;

Related

UIPopoverController? Cannot dismissed when tapping outside the popover controller

I have a problem that began after I changed my project to a universal application and switched to the updated version of Xcode.
At the moment, my application has a navigation bar with a controller that has a button. The button will pop up a UIPopoverController when the user clicks it. Everything was fine here. Now I try to interact with the list inside UIPopoverController and there is no reaction at all in the list. In addition, when I try to dismiss the popover controller by tapping outside the popover controller, the popup does dismiss at all as well as I can even interact the controls behind the popover controller.
It worked fine before I updated Xcode to the latest IOS. Inside the code I have changed was having the xib file to have the window view and inside the app delegate file I initialized that xib file.
This is shown the code below.
TViewController* controller = [[TController alloc] initWithNibName:#"MainViewController_IPad" bundle:NULL];
[controller.navigationController setNavigationBarHidden:TRUE animated:TRUE];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[self.window setRootViewController:controller];
[self.window makeKeyAndVisible];
//((TopicShowViewController*)self.window.rootViewController).navigationController.navigationBarHidden = true;
self.navigationController = ((TopicShowViewController*)self.window.rootViewController).navigationController;
self.navigationController.navigationBarHidden = true;
[controller release];
The code above, I have to create the window object but the TViewController itself has a window object already. If i run this without either window object in the xib file or explicit initialized the window object from code above, the TViewController won't display as expected.
I have no idea what is going wrong here... Sorry the description may be too long to understand but please help.
A universal application is an app designed to run on both an iPhone and an iPad. However, the UIPopoverController is not supported on the iPhone. If you try open a popover on an iPhone your app will throw an exception.

How to push new view controller in didReceiveRemoteNotification so that previous view controller doesnt show for a moment?

I receive a pust notification and push a view controller based on the data i get in push.
I do it like this:
UINavigationController *navVc=(UINavigationController *) self.window.rootViewController;
PictureTakeVC *pvc=[[PictureTakeVC alloc] init];
[navVc pushViewController:pvc animated:NO];
It works, but the view controller that was opened before i pressed home button shows for a moment.
I also tried this but it happens the same:
PictureTakeVC *pvc=[[PictureTakeVC alloc] init];
NSArray *vcs=[[NSArray alloc] initWithObjects: pvc, nil];
UINavigationController *navVc=(UINavigationController *) self.window.rootViewController;
navVc.viewControllers=vcs;
self.window.rootViewController = navVc;
How to push vc didReceiveRemoteNotification so that it opens immediatly and no other vc is shown for a moment?
As you said "but the view controller that was opened before i pressed home button shows for a moment.",
The reason is not the code, but the iOS system.
It captures screenshot of the screen when app goes in background. As documented:
Remove sensitive information from views before moving to the
background. When an app transitions to the background, the system
takes a snapshot of the app’s main window, which it then presents
briefly when transitioning your app back to the foreground. Before
returning from your applicationDidEnterBackground: method, you should
hide or obscure passwords and other sensitive personal information
that might be captured as part of the snapshot.
So, if snapshot is removed then it will directly show the new pushed view controller.
(not sure about apple guideline for snapshot)
Update:
One approach can be:
Add a black colored background on the app screen when it goes in background(in applicationDidEnterBackground method). So, it will show black screen while coming back to application.{ They store it for showing launch image for already started application.}
Where it helps?
When we delete snapshots from 'Preference' directory of application sandbox(after application goes in background) and come back to application it shows black for a while as it does not have any snapshot.
The outcome of our approach and removing snapshot are same.
Since PictureTakeVC is a view controller just use this instead
PictureTakeVC *pvc = [[PictureTakeVC alloc] initWithNibName:#"PictureTakeVC" bundle:nil];
[self.navigationController pushViewController:pvc animated:YES];
Before your app goes into background mode remove the view that is there.
Are you missing something? The didReceiveRemoteNotification fires when your application is active and running.
...but anyway if you want to achieve what you are asking you have to detect there is a pushnotification from didFinishLaunchingWithOptions (or may be from applicationDidBecomeActive or applicationWillEnterForeground) and push viewcontroller on rootviewcontroller from one of these methods.
To detect whether there were remote notification:
NSString *params = [[launchOptions objectForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"] objectForKey:#"View"];
if (params)
{
// push view
}
Use following methods to push view, you won't see any other vc when application gets activated. Let me know if any issues.
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
I have done similar for push notification so let me know what are you trying to achieve exactly if I understood wrong.

ABPersonViewController drawn under the navgation bar

The context:
I am working on an app that maintains a list of contacts along with their record IDs for it's own reference.
When the user needs to change the number associated with a specific contact within the app, I am trying to display the ABPersonViewController so the user can choose the new number from the contact in AB.
The problem:
The problem is that the ABPersonViewController that is opened is starting all the way from the top of the screen as if it does not know that there is a navigation bar on the top.
As a result some of the top part of the ABPersonViewController screen (the top part of the person image and the top part of the name) is underneath the navigation bar.
Ideally i want it to look like this, but not in edit mode: http://developer.apple.com/library/ios/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Art/person_view.jpg
Also I wanted to add a "cancel" button to the top right part of the nav bar. Trying to add that as a bar button is not working either.
The code:
this is how I am adding the ABPersonViewController to the navigationController:
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.personViewDelegate = self;
personViewController.displayedPerson = person;
[self.m_circleNavController pushViewController:personViewController animated:YES];
[personViewController release];
The self here is a UIVIewController.
The m_circleNavController is the UINavigationController to which the UIVIewController belongs.
I tried these 2 ways of showing the person view, but both behave the same way.
[self.m_circleNavController pushViewController:personViewController animated:YES];
[self.navigationController pushViewController:personViewController animated:YES];
I'm not too sure what I am doing wrong, or what is the best way to do it.
I tried a lot of different ways to display it in vain.
The viewcontroller was behaving as though it was starting about 40 pixels above the top edge of the screen.
I was able to fix it in a very weird way finally. In the init function of the viewcontroller I added the following line:
self.view.bounds = CGRectMake(0, -43, 320, 440);
But still no clue as to why it happens this way. I was to close to the deadline to look for a decent solution.
Hello I've been having the same problem as of the new iOS. When this happens on my custom view controllers I have been able to correct it with:
if (self.interfaceOrientation != UIInterfaceOrientationPortrait) { // UI is in landscape position
[self.tableView setContentInset:UIEdgeInsetsMake(32,0,0,0)];
} else { // UI is in portrait position
[self.tableView setContentInset:UIEdgeInsetsMake(44,0,0,0)];
}
But when using the ABPersonViewController I don't quite know how to handle this problem.
Hope someone has an idea...

UINavigationController navigation stack problems in landscape mode

I have an iPhone application that I am currently converting to a universal binary to work with the iPad. I have successfully implemented everything I need in terms of layout so that full landscape functionality is now supported in my app (previously I primarily used portrait mode to display content).
But, I have one strange problem, and it ONLY occurs in landscape mode: when I push a view controller onto the stack, it takes two taps on the back button to return to the previous view controller! The first tap shows a blank view, but with the same name on the left-side back navigation button, the second tap takes the controller back to previous view like it should.
I don't have an iPad to test, so I am relying on the simulator. The problem does not show up on the iPhone and doesn't show up if you rotate back to portrait mode.
My app consists of a tabbarcontroller with navigation controllers loaded for its vc's:
//application delegate
- (void)applicationDidFinishLaunching:(UIApplication *)application
//....
WebHelpViewController *vc8 = [[WebHelpViewController alloc] init];
UINavigationController *nv8 = [[UINavigationController alloc] initWithRootViewController:vc8];
[self.tabBarController setViewControllers:[NSArray arrayWithObjects:nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,nil]];
To implement landscape capability, the UITabBarController is overridden to autorotate when required:
//CustomTabBarController.m
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return [[(UINavigationController *)self.selectedViewController topViewController] shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
... works fine. I navigate into new views using this method
SomeViewController *vc = [[SomeViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
Is this only a simulation error? How do I fix this problem?
It sounds like another ViewController is responding to:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
Check this first.

how can I call a screen with a button action (xcode)?

I am developing a Window Based app for iPhone. I use Interface Builder to build Interface. I want to call a new screen with a Button Action. How can I call the screen with Button action ?
By pushing the new controller onto the top of the stack of windows. For example:
EnterNameController *newEnterNameController = [[EnterNameController alloc] initWithNibName:#"EnterName" bundle:[NSBundle mainBundle]];
[[self navigationController] pushViewController:newEnterNameController animated:YES];
Apple has an extraordinary amount of sample code, and this question (as well as many others) could easily be solved by simply visiting Apple's iPhone dev site.
iPhone Dev Site
If you are using a navigation controller, push it onto the navigation controller's stack, as alamodey suggested.
If you want it to be a modal controller (that is, slide up from the bottom and cover the previous controller's view, like the Bookmarks screen in Safari), present it as a modal view controller:
[self presentModalViewController:myNewController animated:YES];
When you want to bring the old controller back, dismiss the modal view controller. From inside the modal view controller:
[self.parentViewController dismissModalViewControllerAnimated:YES];
If you don't want to do either, just remove the current controller's view from the window and add the new controller's:
UIView * containingView = self.view.superview;
[self.view removeFromSuperview];
[containingView addSubview:myNewController.view];
If you go this route, you may want to look into +[UIView beginAnimations:context:], +[UIView setAnimationTransition:onView:], and +[UIView commitAnimations] (if I recall the method names correctly--check the documentation) to animate the transition. You should almost always animate any switch between screens in iPhone OS.
(work in .m class)
#import "classtocall.h"
- (IBAction)ButtonPressed:(id)sender
{
classtocall *mvc = [[classtocall alloc]initWithNibName:#"classtocall" bundle:nil];
[self presentModalViewController:mvc animated:NO];
}
(for window based application)
define in .h class
- (IBAction)ButtonPressed:(id)sender;
where "classtocall" is the class you want to call.
you just need to download sample applications from XCode help. Try Elements and UIcatalog. There are also other - type 'pushViewController' or 'addSubview' adn 'makeKeyAndVisible' in help and download samples
nextscreenViewController *login = [[self storyboard] instantiateViewControllerWithIdentifier:#"nextscreenidentifier"];
nextscreenidentifier.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController: nextscreenidentifier animated: YES];