Creating additional window in Objective - C - objective-c

I have my viewcontroller with view with 2 buttons. If i press button i want to get new window with search bar + data from my DB. How can I achive it without new VC ?

You basically want to bring another view into your current view controller on the press of a button.
Here will be my approach :
Make a separate class for the view (in your case the search bar and the data from the DB). Also a separate XIB for this would be handy.
Let the class be named 'PopOver'
In Popover.m :
+ (PopOverView*) createInstance {
PopOverView *xibView = [[[NSBundle mainBundle] loadNibNamed:#"PopOverView" owner:self options:nil] objectAtIndex:0];
[xibView setFrame:CGRectMake(CGRectMinXEdge + 10, CGRectMinYEdge + 10, 200, 200)];
// adjust frame according to your need
[xibView setBackgroundColor:[UIColor redColor]];
return xibView;
}
Next : In your view controller, On the tap of the button you would add the following code :
- (IBAction)buttonTapped:(id)sender {
UIView *myPopoverView = [PopOverView createInstance];
AppDelegate *appDel = [UIApplication sharedApplication].delegate;
[appDel.window addSubview:myPopoverView];
}
NOTE : I added the 'PopOver' view to the app delegate's window instead of the VC because in your case you don't want the user to interact with the view controller when you are showing the 'Popover' window. In such cases, its better to present views in the app's window.
ALSO : You can animate your view while you present it. For this, refer this link : addSubview animation
Lastly, you will need to implement your search and your DB functionality within the PopOver view class. (Don't forget to add delegates between your VC and Popover).
Hope this helps.
Thanks !

window is created by default in app delgate when you create a project in xcode and whole app is running on that window.
If I am not wrong you want to create a view and add it on a window.
create a File->New->File->iOS(UserInterface), select view name it
"YourView"
create another File->New->File->iOS(Source), select CocoaTouch class,
name it
"YourView" subclass of "UIView".
YourView *viewObj = [[[NSBundle mainBundle] loadNibNamed:#"YourView" owner:self options:nil] objectAtIndex:0];
AppDelgate *appDelObj = [[UIApplication sharedApplication] delegate];
[appDelObj.window addSubview:viewObj];
your view added on window.

Related

UIView inside a UIViewController or better way to do it?

I have a problem on how to properly do a certain kind of action.
The image below shows a UIViewController, but the second part of the view is a custom UIView (the one with the profile pic, name and Show View button).
The subclassed UIView is allocated using this code:
profileView = [[GPProfileView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 70)];
profileView.myTripGradientColor = YES;
[self.view addSubview:profileView];
The problem is of course, that the button on the UIView can't show any view, since it's only the UIViewController that can push another ViewController to the window(correct?).
The UIView is used in several places in the app and needs to be added easily and have the same behavior across the application.
This worked great until I added the button, and I'm starting to think I've made this wrong, and there has to be a better way to do it (maybe change the UIView to something else?).
I was thinking I should be able to call:
self.superview
And then somehow get the ViewController so I can push another ViewController into the view hierarchy, but nope.
Any suggestions and a tips on how to do this correctly?
UPDATE:
I have no idea on how to push another UIViewController from the button.
What should I do in this method when pressing the button in the UIView:
- (void) showViewButtonTouched:(UIButton*)sender {
GPProfileSocialFriendsViewController *friendsSettings = [[GPProfileSocialFriendsViewController alloc] init];
}
How do I push GPProfileSocialFriendsViewController?
Your - (void) showViewButtonTouched:(UIButton*)sender method should be in your controller and would probably be better named - (void) showView:(UIButton*)sender or - (void) showProfile:(UIButton*)sender so it clearly denotes what it does (not how you got there).
It's not the view's responsibility to manage transitions from a state to another. If you move your method to your controller, your problem is no more (you can easily access self.navigationController or push directly if you don't have an navigation controller like this:
[self presentViewController:vcThatNeedsToBePushed animated:YES completion:nil];
I think you can create weak reference in GPProfileView on UIViewController. Like this:
#property (weak, nonatomic) UIViewController *rootController;
when you create GPProfileView, assign rootController-property:
profileView = [[GPProfileView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 70)];
profileView.myTripGradientColor = YES;
profileView.rootController = self; // if view created in view controller
[self.view addSubview:profileView];
and in implementation of button selector:
self.rootController push... // or pop
May be this not correct, but you can try
You could let the view controller push the next view controller when the button is pushed. The view controller can add a target/action on the button, so that the action method in the view controller is called on the touch up inside event.

SideMenu black view

I am trying to make a sidebar menu but i have a little problem.
I explain :
I created an UIViewController that i called sideMenuViewController
In my viewController Class (the initial view controller), in the header file, i import my class SideMenuViewController and i wrote :
-(IBAction)openSideMenu:(id)sender;
#property(nonatomic, retain) SideMenuViewController *sideMenu;
The openSideMenu action is associated to the menu button.
I implemented this method like this :
- (IBAction)openSideMenu:(id)sender {
CGRect destination = self.view.frame;
if(destination.origin.x > 0){
destination.origin.x = 0;
}else{
destination.origin.x += SideMenuX;
}
[UIView animateWithDuration:0.4 animations:^{
self.view.frame = destination;
}completion:^(BOOL finished) {
if(finished){
}
}];
}
SideMenuX is a macro : #define SideMenuX 154.4
My viewDidLoad method looks like this :
- (void)viewDidLoad
{
[super viewDidLoad];
_sideMenu = [[SideMenuViewController alloc] init];
[self.view sendSubviewToBack:_sideMenu.view];
// Do any additional setup after loading the view, typically from a nib.
}
The problem is that when i click on the menu button, i get a black screen and not my side menu view.
Thank you in advance !
Two problems:
You are not adding the sideMenu at all. Try adding it to the parent view (self.view.superview), which in your case most likely will be the UIWindow: [self.view.superview insertSubview:_sideMenu.view belowSubview:self.view]; If you are using a navigation controller, use self.navigationController.view instead self.view.
Not sure if you initialized the view with a NIB or the Storyboard (see below if you didn't).
Here is a working example. I created the left view controller inside the storyboard like this:
Throw a View Controller component on the storyboard.
Select the controller on the left column, and go to the Identity Inspector on the right column (alt+cmd+3):
Set the Class to SideMenuViewController
Set the Storyboard ID to SideMenuViewController
Instantiate the controller inside viewDidLoad with
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
self.sideMenu = (SideMenuViewController*)[storyboard instantiateViewControllerWithIdentifier:#"SideMenuViewController"];
then insert it as child of the superview.
(Answering the comment below)
This line is the problem:
[self.view.superview addSubview:_sideMenu.view];
In a NIB based project the superview is UIWindow, but in a Storyboard project, the self.view.superview of a UIViewController is nil. You can solve this, for example, adding a UINavigationViewController. Follow these steps:
Throw in a "Navigation Controller"
Delete the view controller it points to.
Press Ctrl and drag the pointer from the UINavigationController to your view controller, and select "root view controller" on the dialog that appears.
Drag the arrow pointing to your view controller to the UINavigationController (the one that marks the initial view controller, not the one that comes from UINavigationController).
Then change your code to
_sideMenu = [[SideMenuViewController alloc] initWithNibName:#"SideMenuViewController" bundle:nil];
[self.navigationController.view.superview insertSubview:_sideMenu.view belowSubview:self.navigationController.view];
To hide the navigation bar of the UINavigationController, select it in the Storyboard and click Hidden in the Attributes Inspector (alt+cmd+4).
All you're seeing is black because you don't have the side menu view added. Try this:
- (void)viewDidLoad {
[super viewDidLoad];
_sideMenu = [[SideMenuViewController alloc] init];
[self.view addSubview:_sideMenu.view];
[self.view sendSubviewToBack:_sideMenu.view];
}

How to addsubview to a view on class1 from class2?

I'm trying to do a really simple thing - I've got a main Xib file for the whole app and another Xib file for a small view.
I want the small view (Xib called "additionalView.xib") to appear in the first Xib ("ViewController.xib").
I have succeeded to do so in the "ViewController.m" but I want more - I want to do it from "additionalView.m"
There is a method I created called "openView:" in "additionalView.m" and it looks like this:
-(IBAction)openView:(id)sender
{
ViewController *vc = [[ViewController alloc] init];
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"additionalView" owner:self options:nil];
UIView *nibView = [nibObjects objectAtIndex:0];
[vc.view addSubview:nibView];
}
The method is being called and the lines are being read by the debugger - but nothing happens.
No crash - No error - No small view in bigger view.
Why is that?
I know that the last line is probably what's
screwing everything up but i don't know how to put it correctly.
Your problem is that ViewController *vc = [[ViewController alloc] init]; creates a new view controller. Because it's new, it's not the one that already exists in the view controller hierarchy that's managing the display.
Your method needs to access the existing view controller. How it does that depends on your app's structure and which object has a reference to the original controller object.
Try
[self.view addView:view.vc];
However, I'm not sure what is you view structure here. You say your -(IBAction)openView:(id)sender is in your "additionalView.m", but it is not the main view controller, correct? You need to do this in the main controller, so basically move the openView: method to your ViewController.m
And you normally need a separate view controller for each view to keep things neat and separate, so the additionalView.m should be an instance of UIViewController, which you can then create from your main view as follows:
-(IBAction)openView:(id)sender
{
AdditionalView *vc = [[AdditionalView alloc] initWithNibName:#"additionalView"];
[self.view vc.view];
}
You have options ... First you don't need to create a view controller vc if you just need the view . Create a uiview and add it .
Option 1: pass a ref to the app vc as suggested above and then :
[appVC.view addsubview:additionalView]
This will add it to main.
Use a view controller manager / ref in the app delegate that you can refer to as delegate and add your view to the current showing view.
Hope this helps

Setting title of UINavigationBar

I have an application which uses a main story board to include a Navigation Controller where the main view is a Table View using a prototype cell content. Each cell in the table view pushes onto a new view which I have created with it's own set of .h .m and .xib files.
The table view navigation bar has its title set through the story board which works fine. However, I am having trouble setting the title for each new view after it gets pushed into view.
I have the following in the viewDidLoad method for each view;
self.title = #"View Title";
Any advice?
it is the right way. it will work.
I'm doing something similar in an app I'm working on. Here's how I'm setting the title:
[[self navigationItem] setTitle:#"My View's Title"];
I thinkt the dot notation equivalent would be something like this:
self.navigationItem.title = #"My View's Title";
Hope that helps.
If you have a tab bar controller, try this:
self.tabBarController.navigationItem.title = #"Title";

How to create a UINavigationItem.TitleView based upon a nib file?

I have a UINavigationController bassed sequence of screens. On one of the screens I want to replace the standard title with a custom TitleView. The custom view will be created with a nib file and will have an image and several labels.
Do I create a UIViewController w/ associated nib file, load the nib, and assign the .view property to the TitleView? Basically, how do I use a nib where I can layout the necessary elements and then assign the resulting view to the TitleView property?
Consider using UINib - it was exposed in iOS 4.0. It double perf since it caches the nib for you.
UINib *nib = [UINib nibWithNibName:#"TestView" bundle:nil];
UIView *myView = [[nib instantiateWithOwner:self options:nil] objectAtIndex:0]];
The objectAtIndex refers to the top level views in the NIB - typically there's one (index 0) but if there's many, you need to provide the index.
Once you have the view you can assign it to the navigationItem titleView
self.navigationItem.titleView = myView;
[myview release];
EDIT:
If you need to get to the individual controls within the NIB, puts tags on them and access them via viewWithTag. See here:
http://useyourloaf.com/blog/2011/2/28/speeding-up-table-view-cell-loading-with-uinib.html
Create your custom view in Interface Builder & load it to a view(or you can create an IBOutlet iVar to point the view). Then just set the titleView to your custom view.
UIView * customTitleView = [[[NSBundle mainBundle] loadNibNamed:#"TitleView" owner:self options:nil] lastObject];
self.navigationItem.titleView = customTitleView;
[customTitleView release];