Reputation: 4685
I'm playing around with a simple test app that just loops through 10 images and displays each one to the view. The next image will be displayed after the user clicks a button. The problem I am having is the view is never appearing (image or button). When I take out the button press clause, the code runs and the last image is displayed. continueRunningScript is initially YES.
@interface ViewController : UIViewController <UIAlertViewDelegate>
{
BOOL continueRunningScript;
UIButton *wrongButton;
UIImageView *imageView;
}
// ...
@end
@implementation ViewController
// ...
- (void) xxx {
for (int i = 0; i<10; i++) {
while (continueRunningScript == NO) {
// Stay here until button is pressed.
}
UIImage *testImg = ... // code to load the image at index i
imageView = [[UIImageView alloc] initWithImage: testImg];
[self.view addSubview:imageView];
wrongButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[wrongButton addTarget:self
action:@selector(incorrectResultButtonPress:)
forControlEvents:UIControlEventTouchUpInside];
[wrongButton setTitle:@"Wrong Result?" forState:UIControlStateNormal];
wrongButton.frame = CGRectMake(80.0, 310.0, 160.0, 40.0);
[self.view addSubview:wrongButton];
continueRunningScript = NO;
[testImg release];
}
[imageView release];
[wrongButton release];
}
// button press handling...
// UIAlertViewDelegate
- (void) alertView: (UIAlertView *)actionSheet clickedButtonAtIndex: (NSInteger)buttonIndex {
// The user clicked one of the Yes/No buttons
if (buttonIndex == 0) // Yes
{
UIAlertView *thankyouAlert = [[UIAlertView alloc] initWithTitle:@"Thank You"
message:@"Thanks for the feedback!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:nil];
[thankyouAlert show];
// Call performSelector delegate method of NSObject to call class method dismissAlertView
[self performSelector:@selector(dismissAlertView:) withObject:thankyouAlert afterDelay:2];
[thankyouAlert release];
[wrongButton removeFromSuperview];
continueRunningScript = YES;
}
}
// ...
@end
Upvotes: 0
Views: 123
Reputation: 70743
UIKit only draws stuff when you return to the main UI run loop. Your code does not return after the first image and before the next, so that first image is never displayed.
Events are also only detected/dispatched in the main UI run loop. Since your code never returns from the first button handler, no subsequent buttons events will be detected.
Upvotes: 0
Reputation: 13675
Is method 'xxx' running on the main thread? If so, the culprit is:
while (continueRunningScript == NO) {
// Stay here until button is pressed.
}
iOS uses an event-driven architecture and it is very bad practice to block the main thread like you are doing here. Your app will loop indefinitely here and will stop updating the UI and will not respond to any button presses or other events. This is why your view, image and button are not appearing.
You need to think about how you can modify your app to fit in with the event-driven architecture.
Upvotes: 1
Reputation: 73966
I'm making the assumption that you aren't doing this on a background thread or anything. If you are, then you should be aware that UIKit is only designed to be used from the main thread.
while (continueRunningScript == NO) {
// Stay here until button is pressed.
}
This will not work the way you want it to. It will enter an infinite loop. The thread of execution will not progress past this point to process any input events, so that variable will never get a chance to be set to YES
.
You have to remember that all of the user interface code will run after you exit from your method. If you take the pure out, then you're looping through all the images that are added, then the user interface is updated. That's why you only see the last image - the others were added too, but they are underneath the top-most (last) one.
If you want a new image to be shown every time the user taps a button, then you should have an instance variable that keeps track of which image is the current one, and write a method to update this variable and show the next image. In almost all circumstances, a busy loop like the above is wrong.
Also, you should be aware that you don't have to add a new UIImageView
every time you want to display a new image. You can simply update the image
property for an existing image view to change which image it is displaying.
Upvotes: 1
Reputation: 2781
I don't think you need to release the imageView or wrongButton. They probably want to be retained for as long as the controller exists.
Beyond that guess, I'd suggest we need more information.
Upvotes: 0