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.
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.
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.
Reading through Apple's docs here, the example code declares the primitive accessor and mutator as separate methods in a category. Is it possible to use #property to declare the primitives? Is there a disadvantage to do it this way; it seems like it saves boiler plate code, but are there performance implications in the way the methods are generated when declared this way? What are the optional attributes - (strong, nonatomic)?
Apple's Example Code
#interface Department : NSManagedObject
#property(nonatomic, retain) NSString *name;
#end
#interface Department (PrimitiveAccessors)
- (NSString *)primitiveName;
- (void)setPrimitiveName:(NSString *)newName;
#end
Suggested Change
#interface Department : NSManagedObject
#property(nonatomic, retain) NSString *name;
#end
#interface Department (PrimitiveAccessors)
#property (strong, nonatomic) NSString *primitiveName;
#end
You should generate classes for your Core Data entities automatically. You do this by pressing the Editor menu and selecting "Create NSManagedObject subclass". This will automatically create a class for each of your entities, and those will have the properties you want.
If you want to customize these classes I strongly recommend that you do it in a category. I recommend this because, you may want to go back to your datamodel and add or remove an attribute, and thus you will have to generate new subclasses. In that event, any changes you may've made to the subclasses will be overwritten and that can be painful :)
I have some existing code in ObjC that I would like to use in a MonoTouch app. I am creating a static lib from the existing code and then using binding to access and use it from the MonoTouch app. Everything is working great except when I attempt to bind to a type derived from NSManagedObject. For some reason it cannot find the property. I get an "unrecognized selector sent to instance" error. I'm guessing it has something to do with #dynamic, but I'm not sure and couldn't find any documentation regarding why this doesn't work.
.h
#interface MyNSManagedObject : NSManagedObject
#property (nonatomic, retain) NSString *clientName;
#end
.m
#implementation MyNSManagedObject
#dynamic clientName;
#end
I am just getting started with the CoreData API and am following a few tutorials. I get the basics of storing and retrieving objects, but am having trouble connecting all the pieces in terms of MVC.
I have a CustomView into which I draw some stuff with CoreAnimation, including some text layers that will get their strings from an NSManagedObject. I started with a basic CoreData application template so the managedObjectContext etc are declared in the appDelegate, and I'm just not sure how I should be getting data from the CoreData stack into the view. By the way, this is all in code, not interface builder.
So my question is, if I want to build my app in a pure MVC way, how should I go about getting data from the stack into the view? How should I give my view access to the initialized NSManagedObjectContext, for example?
I have been reading Cocoa Design Patterns but am a bit of a dunce when it comes to MVC. I know its a pretty general question, but if someone can just say, "set the delegate, grab a pointer..." whatever it is, that would be great!
Thanks in advance!
So I did some more poking around and it seems the easiest way to do this is to get a pointer to the AppDelegate and then a pointer to the managedObjectContext. From there, execute a fetch request and put it into your view!
In a good tutorial Björn Sållarp does it this way:
From the app delegate he creates the rootViewController and sends it the context with:
RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
rootViewController.managedObjectContext = context;
rootViewController.entityName = #"Counties";
In the rootViewController's h file you declare:
NSManagedObjectContext *managedObjectContext;
Create its property:
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
and in m you
#synthesize managedObjectContext;
Then its there for your use.