How to determine method error (Objective C/iPhone/xCode)?
While working through examples presented by Mark and LeMarche, I have encountered a number of situations where things don't work as expected. For example, Chapter 4 discusses 'Spiffing up a button' with an image. I can't seem to get an image stretched on the button, despite the fact that I followed the original instructions and a number of work arounds [1,2,3].
How does one determine the error encountered in a Objective C method which returns void? (IMHO, a useless paradigm). Guessing at the culprit or error is a useless waste of time, and its not working well for me.
Sorry about being snippy - I am at wits end, and I am tired of all the printf's, NSLogs, and guessing. This is no way to develop programs.
Jeff
[1] Resizing an image with stretchableImageWithLeftCapWidth
[2] stretchableImageWithLeftCapWidth:topCapHeight doesn't work in initWithCoder: of UIImageView subclass
[3] iPhone stretchableImageWithLeftCapWidth only makes "D"s
// Source code from Mark and LeMarch ('Beginning iPhone 4 Programming', Chapter 4, pp. 99-100)
// added for completeness. The same code is presented in 'Beginning iPhone 3 Programming'.
// The button type is 'Custom', and the mode is 'Scale to Fill'. Trying to use TIFFs,
// removing Alpha channels, resizing buttons so their size is image.height+1, etc - no joy.
// The buttons were provided by Apple in their UICatalog example (http://developer.apple.com/library/ios/#samplecode/UICatalog/Introduction/Intro.html).
// I've also tried to assign the image to a single button in case the resource cannot be shared.
// Finally, no ASSERTs fire (and no exceptions are thrown), so all should be OK (yea, right).
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage* whiteButton = [UIImage imageNamed:@"whiteButton.png"];
ASSERT(whiteButton != nil);
UIImage* strechableWhiteButton = [whiteButton stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0];
ASSERT(strechableWhiteButton != nil);
[changeSrcFileButton setBackgroundImage:strechableWhiteButton forState:UIControlStateNo开发者_Go百科rmal];
[changeDestFileButton setBackgroundImage:strechableWhiteButton forState:UIControlStateNormal];
UIImage* blueButton = [UIImage imageNamed:@"blueButton.png"];
ASSERT(blueButton != nil);
UIImage* strechableBlueButton = [blueButton stretchableImageWithLeftCapWidth:12 topCapHeight:0];
ASSERT(strechableBlueButton != nil);
[changeSrcFileButton setBackgroundImage:strechableBlueButton forState:UIControlStateHighlighted];
[changeDestFileButton setBackgroundImage:strechableBlueButton forState:UIControlStateHighlighted];
}
You're really asking two questions here, I think: "How do you stretch an image on a button?" and "What do you do when code doesn't work?" I'll take the former first. The following code works for me to create a button from scratch with a stretched image:
UIImage *image = [[UIImage imageNamed:@"ButtonPic"] stretchableImageWithLeftCapWidth:19 topCapHeight:19];
CGRect frame = CGRectMake(80, 200, 160, 40);
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button setBackgroundImage:image forState:UIControlStateNormal];
[self.view addSubview:button];
[button release];
You'll need to supply an appropriate image, naturally. My image is a 80x40 px PNG image created in Photoshop, stretched to a width of 160 px above. Here's what it looks like:
I don't see any significant differences between my code and the code in the book. It looks like the button in the book is loaded from a nib instead of created programmatically, but mine and theirs both call -stretchableImageWithleftCapWidth:topCapHeight: and -setBackgroundImage:forState: to do the relevant work.
That brings us to the second question: "What do you do when code doesn't work?"
There's not a single answer here, but the first thing to do is narrow the problem as much as you can. Arthur Conan Doyle wrote: "Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth." In a case like this one, where you've just got a few lines of code, an easy way to do that is to isolate the problematic code by copying it into a new project. It only takes a moment to create a new iOS project based on the view template, and you can paste the code above into the -viewDidLoad method of the supplied view controller to try it out. Then all you need to do is to supply an image. If it still doesn't work, you've removed all the other code in your app from suspicion. If it does work, you can gradually add some more code from your app in an attempt to reproduce the problem and identify the cause. Moving your code to a test project isn't always feasible, but you can usually find ways to simplify the problem.
As far as errors go, bear in mind that code often fails even when every function and method succeeds. The problem isn't with the components, but with how they're put together.
精彩评论