New to iOS dev. Kindly correct me if i am wrong?
I have a UIWindow, and rootviewcontroller is :
#interface ViewController : UIViewController
{
IBOutlet UIButton *but;
}
#property (nonatomic, strong) UIButton *but;
-(IBAction) butButtonPressed;
#end
ie: If i make this Viewcontroller as a root view controller, the UIView that is available in the ViewController is displayed. Understood.
I have created a new class inherited from UIViewController, and along with its .xib file.
So xib file name is : view1.xib,
My Objective is to display this view when the button is pressed.
Now i have created a button and button press invokes butButtonPressed. Inside of butButtonPressed, i did the following.
myViewController *vcontroler = [[ViewController alloc] initWithNibName:#"view1" bundle:nil];
[self.view.window addSubview:vcontroler.view];
Application crashes. What am i doing wrong ? Kindly point out.
This...
[self.view.window addSubview:vcontroler.view];
...is a really bad strategy (and I seriously wish I knew where people are finding it as a way of showing views). If you create a view controller, you should use it rather than just treating it as a temporary container that you can rip views out of.
If you want vcontroler to look like a child of your first controller (and you have a UINavigationController), use pushViewController:animated:. Otherwise you can show it as modal with presentModalViewController:animated:.
If you only want to add a view to the existing display, put the view in ViewController's hierarchy and show/hide it.
If you absolutely must have it as a sub-controller of ViewController then you need to keep a reference to it and manage its lifecycle inside the owning controller.
Related
I have a newb question, which I have tried unsuccessfully to find answers for on the web. The task is simple: I want to create a core data document-based app but alter the values in some label objects. Using interface builder, I can build the core data model and populate it, using an array controller, table, etc. all without writing any code. So far so good. My test example is to build a core data model with Box entities that have length and width attributes. I would like a label to display the area, i.e. length*width for any geometrically challenged :).
So after browsing around, I've decided I need to create an NSWindowController subclass and use that to update the label when a box in the table is selected. Have attempted this, but have failed. Before I even hook up the label to the window controller, I have a problem. Following the template comments, I added this to Document.m:
- (void)makeWindowControllers
{
NSLog(#"Adding custom Window Controller");
MyWindowController* myWindowController = [[MyWindowController alloc] init];
[self addWindowController:myWindowController];
}
Also added this to the template MyWindowController.m:
- (id)init
{
self = [super initWithWindowNibName:#"MyWindowController"];
return self;
}
The window controller has its own NIB file from Interface builder where I put the table and label etc. The file owner is set to MyWindowController. Probably forgetting other things, but that's what I remember for now.
The log message appears at startup, but then I get an exception "this class is not key value coding-compliant for the key managedObjectContext" before the window appears. I'm guessing that I don't have the window controller hooked up to the document class properly? My other thought is that the array controller is in the window controller nib, not the document nib, so maybe it's looking in the wrong place for the managedObjectContext?
I would try a different approach: Add area to your Box entity as a read-only attribute. Auto-create a Box class with Xcode ("Create NSManagedObject Subclass" menu item in the "Editor" menu when viewing the data model), then add this to Box.h
#property (weak, readonly) NSString * area;
and this to Box.m
- (NSNumber *)area
{
return [NSNumber numberWithDouble:([[self length] doubleValue] - [[self width] doubleValue])];
}
+ (NSSet *)keyPathsForValuesAffectingArea
{
return [NSSet setWithObjects:#"length", #"width", nil];
}
If you do this you can just bind area to a label value like you do for the other Box properties. No need to subclass NSWindowController or watch for changes.
I am hoping someone can help with this issue that I am having using monotouch with xib files.
I am trying to create a subview derived from uiview. In IB I create a class, set its type to that of my custom class, and then link all of the IBOutlets to the custom class (this is where I think the error may be, as I suspect this should be the files owner).
A IB .h file example is
#interface ActivityUtilityView : UIView {
UILabel *_ActivityLabel;
UILabel *_CaptionLabel;
}
#properrty (nonatomic, retain) IBOutlet UILabel * ActivityLabel;
#properrty (nonatomic, retain) IBOutlet UILabel * CaptionLabel;
#End
In the application code this view needs to be loaded at run time using.
var intptr = NSBundle.MainBundle.LoadNib("ActivityUtilityView",parent_controller,null).ValueAt(0);
m_ActivityView = new ActivityView(intptr);
The first issue is that none of the IBOutlets are instantiated.
The second issue is that the view is being created twice, from what I can tell.
Please can anyone help?
EDIT
I have discovered that half the problem is that the outlets are not instantiated until the view is displayed.
So how can I force a subview to be displayed?
I found a solution that works.
m_ActivityView = Activator.CreateInstance<ActivityUtilityView>();
var view = NSBundle.MainBundle.LoadNib("ActivityUtilityView",m_ActivityView,null);
m_ProgressView = Runtime.GetNSObject(views.ValueAt(0) as ActivityUtilityView;
Creating the view using the IntPtr constructor does not instantiate the IBOutlets until the view has been displayed. This method appears to.
To clarify the issue arrose due to a race condition on background worker threads.
I have seen scattered information related to this subject across stackoverflow and other sites, but nothing comprehensive. I've wasted hours upon hours trying to get this to work to no avail. However, I see in this post on stackoverflow (http://stackoverflow.com/questions/7909906/extracting-nibs-xibs-from-storyboards-ios), but nothing with step by step details.
I have only a single view controller (HomeViewController) in my storyboard, and it is extended from a navigation controller.
Can someone please help me identify exactly what all needs to happen to make this work?
Please correct me, add to, etc to make these steps correct:
Create a new XIB (say, HomeViewController.xib)
Copy all items from the storyboard's view controller into this xib
Set the Class type for the view controller to be HomeViewController class.
Hook up all of the IBOutlets and IBActions.
?? - Should I make the xib contain a navigation controller which contains the UIViewController, or should I set the File's Owner to the HomeViewController class??
Add new Window property in the AppDelegate class.
Create a new MainWindow.xib. What setup needs to happen here? (a) File's Owner to UIApplication; (b) Drag new Object to the "Objects" panel and set it's class to my AppDelegate class; (c) Drag new Window to the "Objects" panel; (d) Connect the IBOutlet for the AppDelegate Window property to this new window object.
Go to the project settings (click on the project in the Project Navigation tab, select the target), and clear the "Main Storyboard" field and set the Main Interface to what? HomeViewController? Or Main Window?
Make the change in the AppDelegate class as shown below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
This is all I know to do, but it still doesn't work. What am I missing?
In my app i have one UIViewController and there are many UIView which i want to load on particular action (for instance BTN Tap) so how can i achieve this programatically .
if any one has solution please let me know.
Thnx in advance
you can bind all the views using IBOutlet like suppose you have view1 and view2 and one default view. Now you want to display view1 on btnTap then you can do like this [self.view addSubview:view1]; make sure to bind the view using IBOutlet
You can use the addSubview method of UIView, like this:
[controller.view addSubview:subview];
where controller is your UIViewController (of course, if you are putting that code inside of it, your controller is self).
I am trying to implement Leah's "Pull to Refresh" code (https://github.com/leah/PullToRefresh) in to my UITableView. However, I have a UIView, so cannot subclass the tableViewController as is required by this.
My structure is
UIView
- UITableView
So there's a UITableView inside my main UIView. I use a UIViewController obviously - and this cannot really change (I think!)
I have tried to change the class in interface builder to the custom uitableviewcontroller above (the pull to refresh one) but it doesn't let me.
Any ideas on how I can subclass the UITableView - NOT the tableViewController??
Here is how I did it:
Change PullToRefreshTableViewController so that it subclasses UIViewController, NOT UITableViewController. Next, add a UITableView * property called tableView to PullToRefreshTableViewController and synthesize it. Lastly, modify your view controller so that it subclasses PullToRefreshTableViewController instead of UIViewController.
That should give you a working implementation of it.