I'm messing around with the iphone sdk and with universal apps. I have UITextView in both my iphone class and a shared class I called Shared (In my Shared class the UITextVIew is called textInput).
I have a UIButton that when pressed, calls a method of the Shared class since I allocate an instance of the Shared class when app finishes launching and gets the value from the UITextView in the Shared class and sets the UITextVIew to that text. I would think that would work, however in my IBAction method for the button being pressed, I've tried it two different ways of:
[textInput setText:#"Accessing web service..."];
// textInput.text = #"Accessing web service...";
NSLog(#"self textInput: %s", [self textInput].text);
However, my NSLog shows null which I don't understand. But if I did something similar and in my UITextView of my iphone app delegate.m, if when the button is pressed, instead of calling the Shared method, I just said
textView.text = #"Hello"; // textView is the UITextVIew in my iphone class
it works. So I am having trouble seeing the disconnect. Any thoughts? Thanks.
Looks like it's just your NSLog call that's in error. NSLog uses %# as an output specifier for NSStrings.
NSLog(#"self textInput: %#", textInput.text);
Related
I have 2 xibs, one for iPad and one for iPhone.
However, currently I have only one view controller for those 2 xibs that works for both iPhone&iPad.
Inside my iPad Xib I have an IBOutlet that doesn't belong to the iPhone xib.
How should I define that outlet ?
I notice that if I put inside my deallc method, something like this :
-(void) dealloc
{
[outletOnlyForIpad release]
}
The app crashes on the iPhone. Apparently cause it doesn't instantiates well on the iPhone. (I hoped it would stay nil, but it's not the case)
I didn't find any preprocessor macro that I can use so I can declare that Outlet only for iPad.
Is the only way to do it is by checking in runTime something like :
isIpad()
[outletOnlyForIpad SomeMethodOnTheOutlet]
In every place in my controller ?
Your code is correct. That outlet should be staying nil, so sending it a release message should be harmless. Rather than work around the error, I suggest you check where this outlet is being set and fix the cause of the problem. Are you certain you aren't connecting anything to it in the iPhone nib?
You have to check at run-time for the device and handle the outlets then if you want separate outlets.
If I create an app with different controls on different devices, I tend to create them programmatically to avoid connection problems such as this.
in your dealloc to avoid the crash on iPhone, and connect the IBOutlet as usual in your iPad xib:
-(void) dealloc
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[outletOnlyForIpad release]
}
}
When you initialize your class, all instance variables are automatically initialised to zero. Thus this is the equivalent of adding:
outletOnlyForIpad = nil;
To your init method.
This nil value will be overwritten when the view loads for the iPad but not the iPhone (unless you have other code that sets it). However your [outletOnlyForIpad release] crash shows that outletOnlyForIpad is not nil at this point, which means that something has given it a value. You need to find out what this something is - it may be your interface builder file.
I'm only starting to developing iOS apps. So the question is gonna be nooby i guess..
I'm trying to understand how the mvc model works in iOS developing.
I want to mix available views and my own (which I want to draw by myself using primitives such as drawing strings)
So
I created the MyView:UIView class. Then I overrided drawRect method and added there a simple output. Then I added my class to the "ipad display" using interface builder.
And the problem is that breakpoint in the beginning of the DrawRect method never gets reached. And of course I get a blank screen in simulator=(
I've tried to add ViewController and use it in the interface builder but in fact i don't need it because my view just draws a constant string and that's all...
I guess I misunderstand something very serious because looking through apple examples got nothing for me.
Here's my code (sorry, forgot about it):
MyView.h:
#interface MyView : UIView {
...
}
MyView.m:
...
- (void)drawRect:(CGRect)rect {
NSString *text = #"Hello, world";
UIFont *font = [UIFont systemFontOfSize:10];
[[UIColor blackColor] set];
CGPoint point;
point = CGPointMake(0.5f, 0.5f);
[text drawAtPoint:point withFont:font];
[font release];
}
UPD:
I've added a TabBar just to make sure that the problem is only with my own view. That's it: TabBar appears.
As you didn't post your code, this is a wild guess, but you need to make the view re-render:
[myViewInstance setNeedsDisplay:YES];
Also, make sure the view is actually loaded. You can check this with a little NSLog in the nib awaking method (-[<NSNibAwaking> awakeFromNib]).
If drawRect: is not being called, then either you are not actually onscreen, or you have put in the wrong signature for drawRect:. The correct signature is:
- (void)drawRect:(CGRect)rect
To make sure you're actually onscreen, try overloading awakeFromNib and putting a breakpoint there. If you're not, then you have not configured it correctly in interface builder. The most common problems are failure to set the correct class for the view (it should be set to MyView), or putting it into a NIB that is not actually loaded.
And of course make sure that you are actually a subclass of UIView, that you do not have any warnings from the compiler or from Interface Builder, and that there are no messages printed to console when you run.
OK, so I have an app with a UITextView that I want to exhibit standard Undo behaviour. I have trawled lots of tutorials and answers on this site as well as the Apple Developer Docs and I can't understand why what I have produced is not working.
Whenever the UITextView is modified (I am using a non-standard keyboard using the textView.inputView property) the method below is passed a string that is the new text required for the text view:
- (void)setText:(NSString*)text{
NSString *oldText = [textView.text mutableCopy];
if (text != oldText) {
[undoManager registerUndoWithTarget:self selector:#selector(setText:) object:oldText];
textView.text = text;
}
}
and then to implement the undo when a UIButton is pressed
[undoManager undo];
is executed.
I have declared undoManager in my header file using
NSUndoManager *undoManager;
and synthesised it in my implementation but when I press the undo UIButton nothing happens and setText is never called. Where am I going wrong?
I think the initialisation of the undoManager is still missing in your example. You declare
NSUndoManager *undoManager;
in you headerfile, but I do not see where you allocate/initialize it.
Try adding
undoManger = [NSUndoManager alloc] init];
in you i.e. "viewDidLoad" (or similar) method. Do not forget to release the object appropriate, when you don't need it anymore, for example in dealloc.
Using iPhone SDK 4.1. Sometimes when returning from the background state on iPhone 3GS device the view returned to has lost one of its images or labels. The viewDidAppear method
doesn't get called either when returning from the background. Is there any way to force
reloading the view so these methods are called?
This usually happens if your app receives a memory warning as a result of trying to store too much data in ram (in this case images).
To test whether this is the case you could either do an NSLog call inside the didReceiveMemoryWarning message or you could subclass UIImage and extend its dealloc and put an NSLog message inside it saying something like "Image being dealloced" and then check what gets written to the console. If you want to check it without being in the debugger (and therefore no console) you could create a debug UILabel inside the mainwindow xib at the very front (so its always visible) whose text value is set instead of writing to NSLog. This way youll be able to see what happened even after you return to your program.
Your best bet is the didReceiveMemoryWarning together with a UILabel object.
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
debugLabel.text=#"Did receive memory warning";
}
To solve the problem (i.e. to reload the images) you could register that view to receive
the UIApplicationWillEnterForegroundNotification from the notification center and then call the necessary reloading calls i.e. check which images are nil (have been released) and should be reloaded.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(viewNeedsReload) name:UIApplicationWillEnterForegroundNotification object:nil];
- (void) viewNeedsReload
{
//Check validity of each image here and reload if necessary
}
I have created a nib file and added a UIWebView. i created an IBOutlet and attached web view with that outlet. till here everything is fine . now when i set the delegate of that webview to self in ViewDidLoad, and implement two of its delegate methods. the application crashes, i m not writing anything in the methods , i have just implemented and the application is crashing ....
what could b the problem ?
is there any problem ???
There is a problem if one of the delegate methods is
– webView:shouldStartLoadWithRequest:navigationType:
Indeed, this method returns a BOOL (YES if the web view should begin loading content; otherwise, NO). Therefore, since you are not writing any code inside the method, this may cause a problem. Try inserting in this method the statement
return YES;
The other delegate methods return void, so these should not be the cause of the problem.