委任が正常に機能しているように見えることを除いて、状況はthis my other questionで説明されている状況と非常に似ています。私は自分のコードについてもう少し詳しく説明しています。関係のない/些細な部分を取り除いているだけです。
ReportScreen.h
@interface ReportScreen : UIViewController <UIImagePickerControllerDelegate, UITextViewDelegate, MBProgressHUDDelegate, SoapDelegate, MapLocationChoiceDelegate>
// ...
@property (nonatomic, retain) MKPointAnnotation *annotation;
@property (nonatomic, retain) IBOutlet UITextView *textView;
@property (nonatomic, retain) IBOutlet UIButton *cameraButton;
@property (nonatomic, retain) IBOutlet UIButton *libraryButton;
@property (nonatomic, retain) IBOutlet UIButton *locationButton;
@property (nonatomic, retain) IBOutlet UIButton *sendButton;
@end
ReportScreen.m
@implementation ReportScreen
@synthesize annotation;
@synthesize textView;
@synthesize cameraButton;
@synthesize libraryButton;
@synthesize locationButton;
@synthesize sendButton;
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Here I used to store the VC's state to a file but it shouldn't be needed now that I'm assigning it as delegate and said delegate seems to still be there even after a memory warning.
}
- (void)viewDidLoad {
[super viewDidLoad];
placeholderText = @"Tell us what's wrong…";
textView.text = placeholderText;
self.annotation = nil;
[self isReadyToSubmit];
hud = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view addSubview:hud];
hud.delegate = self;
hud.labelText = @"Invio in corso…";
hud.dimBackground = YES;
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Here I used to restore the state of the VC from file but… y'know.
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self isReadyToSubmit];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"goToMap"]) {
MapScreen *vc = (MapScreen *)segue.destinationViewController;
// HERE's the magic
vc.mapLocationChoiceDelegate = self;
// MAGIC ends
if(self.annotation != nil) {
vc.annotations = [[NSMutableArray alloc] init];
[vc.annotations addObject:self.annotation];
}
}
}
- (BOOL)isReadyToSubmit {
if(self.annotation != nil) {
locationButton.highlighted = YES;
}
if(![textView.text isEqualToString:placeholderText] && self.annotation != nil) {
[sendButton setEnabled:YES];
} else {
[sendButton setEnabled:NO];
}
return [sendButton isEnabled];
}
- (void)textViewDidBeginEditing:(UITextView *)theTextView {
if([theTextView.text isEqualToString:placeholderText]) {
theTextView.text = @"";
}
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(didFinishEditing:)];
[self.navigationItem setRightBarButtonItem:done animated:YES];
}
- (void)textViewDidEndEditing:(UITextView *)theTextView {
if([theTextView.text isEqualToString:@""]) {
theTextView.text = placeholderText;
}
[self isReadyToSubmit];
}
- (void)didFinishEditing:(id)sender {
[self.navigationItem setRightBarButtonItem:nil animated:YES];
[self.textView resignFirstResponder];
}
// THIS is my delegate protocol's method
- (void)locationChosen:(MKPointAnnotation *)theAnnotation {
self.annotation = theAnnotation;
NSLog(@"R: %@", textView.text);
}
@end
MapScreen.h
@protocol MapLocationChoiceDelegate <NSObject>
- (void)locationChosen:(MKPointAnnotation *)annotation;
@end
// ---
@interface MapScreen : UIViewController <MKMapViewDelegate>
- (void)handleLongPress:(id)sender;
@property (nonatomic, retain) NSMutableArray *annotations;
@property (nonatomic, retain) IBOutlet MKMapView *mapView;
@property (weak) id<MapLocationChoiceDelegate> mapLocationChoiceDelegate;
@end
MapScreen.m
@implementation MapScreen
@synthesize annotations;
@synthesize mapView;
@synthesize mapLocationChoiceDelegate;
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidLoad {
[super viewDidLoad];
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.0;
[self.mapView addGestureRecognizer:lpgr];
[mapView addAnnotations:self.annotations];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
#pragma mark - Map handling
- (void)handleLongPress:(id)sender {
if(![sender isKindOfClass:[UILongPressGestureRecognizer class]]) {
return;
}
UILongPressGestureRecognizer *gr = (UILongPressGestureRecognizer *)sender;
if (gr.state != UIGestureRecognizerStateBegan) {
return;
}
CGPoint touchPoint = [gr locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate = [self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = touchMapCoordinate;
self.annotations = [NSMutableArray arrayWithArray:[mapView annotations]];
for(id a in self.annotations) {
if(![a isKindOfClass:[MKUserLocation class]]) {
[mapView removeAnnotation:a];
}
}
[mapView addAnnotation:annotation];
self.annotations = [NSMutableArray arrayWithArray:[mapView annotations]];
// NSDictionary *userInfo = [NSDictionary dictionaryWithObject:annotation forKey:@"annotation"];
// [[NSNotificationCenter defaultCenter] postNotificationName:@"PositionChosen" object:nil userInfo:userInfo];
[self.mapLocationChoiceDelegate locationChosen:annotation];
NSLog(@"M: %@", ((ReportScreen *)self.mapLocationChoiceDelegate).textView.text);
}
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation {
if([annotation isKindOfClass:[MKUserLocation class]]) {
return nil;
}
static NSString *AnnotationIdentifier = @"Annotation";
MKPinAnnotationView* pinView = (MKPinAnnotationView *)[theMapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView) {
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.animatesDrop = YES;
} else {
pinView.annotation = annotation;
}
return pinView;
}
@end
問題は次のとおりです。
- ReportScreen は MapScreen をプッシュします (実際にはセグエを実行します)。
- UITextView にデータがある場合、または ReportScreen のボタンに状態を設定し、MapScreen がプッシュされている間にメモリ警告が表示された場合、ReportScreen に戻ると、これらのすべてのフィールドにそれらの設定が表示されません。どうやら textView.text はまだ設定されているようで、ボタンの状態も同様で、表示されていません。
質問: なぜですか?