We have a requirement to change UIDocumentInteractionController preview screen? Is it possible to change the rect of UIDocumentInteractionController? I want to open document preview in my custom view?
in creating an AIR Native Extension, I needed to create a view window for my custom view controller.
make sure you are doing:
#import "MyCustomViewController.h"
in my function:
MyCustomViewController *myViewController;
id delegate = [[UIApplication sharedApplication] delegate];
UIWindow *win = [delegate window];
myViewController = [[MyCustomViewController alloc]init];
[win addSubview:myViewController.view];
[myViewController previewDocument: (parameters to method)];
return (_bridge FREObject)(myViewController);
where you implement this may be different depending on your structure. Since I am using it as an ANE, I put it right into the Context function call.
hope it gives you a starting point if you haven't gotten it yet.
Related
I am trying to create a UITableView using storyboard but I came to something that at the end may be easy but I have no idea how to solve it.
First of all let me point out that I know that one of the limitations of storyboards is that you will have to dig through the storyboard to find information about a view you have and link it to the app delegate.
I have create my mutable array and the information that I will use in the table in the app delegate and now I want to reference that UITableView to the app delegate. The hierarchy goes like that
First I have the root view that once you click on a button it will redirect you to the second view
Inside the second view there is another button that once you press it it will redirect you to the UINavigationController
The UINavigationController contains the UITableView.
Therefore as you can see there are two views before the navigation control and the UITableView.
Here is the code I am trying to use but it does not work
UIViewController *viewController = (UIViewController *)self.window.rootviewController;
// The next line refers to the second view but does not work at all
UIViewController *secondView = [[UIViewController viewController] objectAtIndex:1];
//Then the following line is to redirect from the second view to the navigation controller
UINavigationController *navigationController =[[secondView viewController] objectAtIndex:0];
//Then is the table view
BuildingsViewController *buildingsViewController = [[navigationController viewControllers] objectAtIndex:0];
The above code does not work. Can anyone please help me?
Thanks a lot
If this code is in the app delegate there are a variety of reasons why it will probably not work. Firstly you appear to be mixing up View's, ViewControllers and Navigation controllers with what you are trying to do. Secondly there is no guarantee at the time you are trying to do this that all of the views/viewcontrollers have yet been created yet or are joined in the way they will be when the final building view controller is rendered.
What you could try instead is in your BuildingsViewController (which you say is your table view controller) you can get a handle to the App Delegate by using
MyAppDelegate *myAppDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate
Once you have a handle to the delegate you can simply reference your mutable array structure etc. that you created on it from within your BuildingsViewController.
e.g. in the 'numberOfRowsInSection' method:
MyAppDelegate *myAppDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate
NSMutableArray *myBuildings = myAppDelegate.buildingArray;
return [myBuildings count];
Or in the cellForRowAtIndexPath method:
// something like this but using your names for app delegate, building array and the accessor for the building name
MyAppDelegate *myAppDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate
NSMutableArray *myBuildings = myAppDelegate.buildingArray;
cell.textLabel.text = [myBuildings objectAtIndex indexPath.row].theBuildingName;
I have a view that is UIViewController (root) that handles ads and a UINavigationController. In that UINavigationController I have typical layers of controllers. In my custom settings table view controller, I have a button to contact me for support. When the user clicks this button I create a MFMailComposeViewController and would like to present it. I can't present it from the settings table view as it will be underneath my ads, so I need to reference the root view and present it from there. I've tried self.parentViewController.parentViewController where self is the settings table view, but that doesn't work. How should I reference this. It seems like a bad design to have to reference the root view directly and pass it to the settings view.
Get the current keyWindow:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
Get its rootViewController:
UIViewController *rootViewController = window.rootViewController;
NOTE: If an UIAlertView is currently being shown, a new window is being created and assigned to be the keyWindow. There might be other exceptional cases as well that will not keep your application window to be the keyWindow.
In my experience, this is the ideal solution to get the rootViewController:
[[[[UIApplication sharedApplication] delegate] window] rootViewController]
Note: In-case of an active UIAlert or UIActionSheet, you get the Alert or Action Sheet as your key window.
Use the app singleton. Something like:
[[[UIApplication sharedApplication] delegate] rootViewController] should get it if your viewController that is the root is named rootViewController
You can always solve this with 1 line of code but I recommend this Swift way to do it, you can call this from anywhere, its also crash and bug safe:
/// EZSwiftExtensions - Gives you the VC on top so you can easily push your popups
var topMostVC: UIViewController? {
var presentedVC = UIApplication.sharedApplication().keyWindow?.rootViewController
while let pVC = presentedVC?.presentedViewController {
presentedVC = pVC
}
if presentedVC == nil {
print("EZSwiftExtensions Error: You don't have any views set. You may be calling them in viewDidLoad. Try viewDidAppear instead.")
}
return presentedVC
}
Its included as a standard function in:
https://github.com/goktugyil/EZSwiftExtensions
Get the UIApplication object.
Cycle through the windows array to find the keyWindow.
And then get the rootViewController property.
i am using a UINavigationController in my application.
in the first view i am displaying some information and have a button for loading an picture from the camera. this works fine so far. when the picture was loaded, i want to display the picture in a UIImageView within a second view. Therefore i am using the following code.
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
CorrectedImageController *imageController = [[CorrectedImageController alloc] initWithNibName:#"CorrectedImageView" bundle:nil];
self.correctedImageViewController = imageController;
[imageController release];
[delegate.navController pushViewController:imageController animated:YES];
The second view is loaded and the picture is shown. But i get an EXC_BAD_ACCESS message in the Debugger Console and my Application blocks the UI.
In the second view the picture is loaded as follows:
- (void)viewDidLoad {
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[imageView setImage:delegate.correctedImage];
[super viewDidLoad];
}
Can anybody tell me, what i did wrong ?
My nib file looks:
-File's Owner (Corrected Image Controller)
-First Responder (UIResponder)
-View (UIView)
--ImageView (UIImageView)
The File's owner view property is connected to the view.
And the imageView property is connected to the ImageView.
Can anybody tell me, what i did wrong ?
BR,
Martin
I believe this is because you are calling release on the imageController (line 5) and then trying the pushModalView the object you just released (line 6). If your self.correctedImageViewController is retaining the imageController, you could push the self.correctedImageViewController or release the imageController after the push.
Sorry for the newbie question. I have a UITabBar in my main window view as well as an array of UINavigationControllers for each Tab. The structure is similar to the iPod app in that the main views can be seen by selecting TabBar items and then the user can drill down further with the NavigationController by pushing views to the stack.
What I would like to be able to do is to do the equivalent of pressing a TabBar button at the bottom from any of the subviews in code (i.e., change the selected property of the TabBar and display launch the first view controller for the tab).
Any help would be greatly appreciated.
Dave
[myTabBarController setSelectedIndex:index]
EDIT: Answering the part 2 question from the comment:
You can define a method in AppDelegate for switching to a different tab.
And you can get hold of appdelegate from anywhere and send a message..
something like:
MyAppDelegate *appDelegate = (MyAppDelegate*) [[UIApplication sharedApplication] delegate];
[appDelegate SwitchToTab:index]
alternatively...
[self.parentViewController.tabBarController setSelectedIndex:3];
I'd like to reply to Prakash, but can't figure out how. Maybe I'm blocked until my score goes up.
Anyhow, I hope this helps someone:
I was doing what Prakash said, and nothing was happening. It's because to get a pointer to my app delegate, I was doing this:
AppDelegate_Phone *appDelegate = [[AppDelegate_Phone alloc] init];
When I should have been doing this:
AppDelegate_Phone *appDelegate = (AppDelegate_Phone *) [[UIApplication sharedApplication] delegate];
Newbie mistake.
For this, You just need to take UITabBar controller -
.h File -
UITabBarController *_pTabBarController;
#property (nonatomic, retain) IBOutlet UITabBarController *_pTabBarController;
.m File -
// synthesize it
#synthesize _pTabBarController;
At initial load
// You can write one function to add tabBar -
// As you have already mentioned you have created an array , if not
_pTabBarController = [[UITabBarController alloc] init];
NSMutableArray *localViewControllersArray = [[NSMutableArray alloc] initWithCapacity:4];
UINavigationController *theNavigationController;
_pController = [[Controller alloc] initStart];
_pController.tabBarItem.tag = 1;
_pController.title = #"Baranches";
theNavigationController = [[UINavigationController alloc] initWithRootViewController:_pController];
theNavigationController.tabBarItem.tag = 1;
theNavigationController.tabBarItem.image = [UIImage imageNamed:#"icon_branches.png"];
[localViewControllersArray addObject:theNavigationController];
[theNavigationController release];
than you can set index as per your needs
self._pTabBarController.selectedIndex = 0; // as per your requirements
[self.parentViewController.tabBarController setSelectedIndex:3];
Selected the index for me but it just highlighted the navbarcontroller's index as the active index, but while it highlighted that index it was actually on a different viewcontroller than was suggested by the tabbarmenu item.
Just wanted to add that I used this from my view controller, and it performed like someone actually pressed the menuitem; from code:
UITabBarController *MyTabController = (UITabBarController *)((AppDelegate*) [[UIApplication sharedApplication] delegate]).window.rootViewController;
[MyTabController setSelectedIndex:1];
Thank you for this post/answers it helped out a lot in my project.
I wanted to do something similar but for XCode 6.4 iOS (8.4) setSelectedIndex by itself won't do it.
Add the view controllers of the tab bar to a list and then use something like the following in some function and then call it:
FirstViewController *firstVC = [[self viewControllers] objectAtIndex:0];
[self.selectedViewController.view removeFromSuperview]
[self.view insertSubview:firstVC.view belowSubview:self.tabBar];
[self.tabBar setSelectedItem:self.firstTabBarItem];
self.selectedViewController = firstVC;
You might have similar code already inside your didSelectedItem..
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
if (item == self.firstTabBarItem)
// Right here
}
else if ...
}
I have got my own custom UIViewController, which contains a UIScrollView with an UIImageView as it's subview. I would like to make the image to auto rotate when device orientation changes, but it doesn't seem to be working...
In the header file, I've got;
#interface MyViewController : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *containerView;
UIImageView *imageView;
}
These components are initialised in the loadView function as below;
containerView = [[UIScrollView alloc] initWithFrame:frame];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://..."]];
UIImage *image = [[UIImage alloc] initWithData:data];
imageView = [[UIImageView alloc] initWithImage:image];
[image release];
[containerView addSubview:imageView];
And I have added the following method, assuming that's all I need to make the view auto-rotate...
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
MyViewController loads fine with the image I've specified to grab from the URL, and the shouldAutorotate... function is being called, with the correct UIInterfaceOrientation, when I flip the device too.
However, didRotateFromInterfaceOrientation method do not get called, and the image doesn't seem to rotate itself...
Could someone please point out what I need to add, or what I have done wrong here?
Thanks in advance!
This may not be the right answer for you, because you don't specify the context that the UIViewController's in, but I just found an important gotcha in the Apple documentation that explains the similar problem I'm having.
Tab bar controllers support a portrait
orientation by default and do not
rotate to a landscape orientation
unless all of the root view
controllers support such an
orientation. When a device orientation
change occurs, the tab bar controller
queries its array of view controllers.
If any one of them does not support
the orientation, the tab bar
controller does not change its
orientation.
I've noticed that there are issues when rotating a UIView that's not the first or only view as a direct child of the main window.
So if your UIView is part of a Navigation Controller or a Tab View Controller, you'll also need to override shouldAutoRotateToInterfaceOrientation on the Navigation Controller or Tab View Controller.
Also: using [UIApplication setStatusBarOrientation] helps to work around things if/when you need to do it manually.
To make this kind of thing work in my application, I had to override
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
[self layoutSubviews];
}
and also layoutSubviews
- (void)layoutSubviews
{
NSLog(#"layoutSubviews called");
...recalc rects etc based on the new self.view.bounds...
}
I'm not sure that this is absolutely required, but it worked for me.
Sometimes, if you add a subview to a view, it's your responsibility to make sure that the methods are passed to the subview; a couple of days ago I wrote a short post about this. For example, if you have a UIViewController and add a UINavigationController as subview, you must add this code to the UIViewController if you want viewWillAppear:animated: to be called when UINavigationController.view appears:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[projectNavigationController viewWillAppear:animated];
}
It might be the case that the willRotateToInterfaceOrientation and didRotateFromInterfaceOrientation method also need to be called by the superview; I am not really sure about this, but give it a try.
This is discussed in Apple Technical Q&A QA1688.
Sometimes if you stack multiple views on top of each other for some reason, the anotherController might not receive rotation event.
[myWindow addSubview:primaryViewController.view];
[myWindow addSubview:anotherController.view];
A lazy way (not a good design) to fix this is only add one subview on window, but initialize multiple controller on the app delegate. Then when you need to switch window, remove the current view and add the view you want
[self.view removeFromSuperview];
AppDelegate *dg = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[[dg window] addSubview:[[dg viewController] view]];
I just came across this having a similar problem. I have a series of view controllers/complex views, that all rotate perfectly and couldn't figure out why the new one I just added on wasn't rotating. After a LOT of trial and error, the reason was that I wasn't calling the init method (it's the standard init method) when allocating the view controller;
e.g. I was doing
m_timerViewController = [TimerViewController alloc];
instead of
m_timerViewController = [[TimerViewController alloc] init];
To expand on jonoogle's post. I had a similar error. My view has a nib and my custom init:
- (id)initWithCategory:(Category *)category inManagedObjectContext:context{
didn't include the call to init the nib.
self = [super initWithNibName:nil bundle:nil];
Adding that line made my view rotate like it is supposed to.
I copied this from this link
And it works for me.... Reason why i have added this here is to make it easy for others to find. It took me many hours to find this fix:
Make a new set of class files of the UIViewController type, go into the .h file of this class and change this line
#implementation MyTabBarController: UIViewController {}
#end
to something like this
#implementation MyTabBarController: UITabBarController{
}
Now go into the nib file and click on the UITabBarController object and go to it's identity tab, and make it Class MyTabBarController.
now in MyTabBarController.m make sure this is in it.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io {
return YES;
}
You can probably get rid of everything else in there if you want.
just do this if you what to rotate from landscape to portrait!
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}