一些 IBOutlet 指向 nil
经过很长一段时间,我终于再次开始使用 Objective-C,这是迄今为止我唯一完整的应用程序。目标是最终针对 ARC 和可能的故事板进行重构,但目前我正在完善 iOS 4.x 目标。我很生疏,所以如果这是一个愚蠢的问题,请别跟我说。
我的主视图中有一个按钮可以触发 showAction 方法。方法如下:
- (void)showAbout
{
AboutViewController *aboutView = [[[AboutViewController alloc] init] autorelease];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
aboutView.modalPresentationStyle = UIModalPresentationFormSheet;
}
else
{
aboutView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
}
[self presentModalViewController:aboutView animated:YES];
}
AboutViewController 类有这个 .h:
@interface AboutViewController : UIViewController <UIActionSheetDelegate, MFMailComposeViewControllerDelegate> {
}
- (IBAction)dismiss:(UIButton *)sender;
- (IBAction)feedback:(UIButton *)sender;
@property (retain) IBOutlet UIButton *dismissButton;
@property (retain) IBOutlet UIButton *feedbackButton;
@property (retain) IBOutlet UIImageView *background;
@property (retain) IBOutlet UITextView *textView;
@end
并且所有内容都已在 .xib 文件中正确连接(iPhone 和 iPad 也是如此)。操作按预期触发,并且可以访问插座,但只能在 iPhone 上访问。在iPad上运行时,只有textView被正确初始化,其余所有都指向nil。
在 .m 中,我尝试过这个:
@implementation AboutViewController
@synthesize dismissButton = _dismissButton;
@synthesize feedbackButton = _feedbackButton;
@synthesize background = _background;
@synthesize textView = _textView;
// ...
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"obj self.dismiss: %@", self.dismissButton);
NSLog(@"frame dismiss: %@", NSStringFromCGRect(self.dismissButton.frame));
}
在 iPhone 上,我得到这个:
2012-02-08 22:51:00.341 myapp[17290:207] obj self.dismiss: <UIButton: 0x70281d0; frame = (180 410; 120 30); opaque = NO; autoresize = LM+W+RM+TM; layer = <CALayer: 0x7028260>>
2012-02-08 22:51:00.342 myapp[17290:207] frame dismiss: {{180, 410}, {120, 30}}
相反,在 iPad 上,我得到这个:
2012-02-08 22:51:40.428 myapp[17320:207] obj self.dismiss: (null)
2012-02-08 22:51:40.428 myapp[17320:207] frame dismiss: {{0, 0}, {0, 0}}
根据 UI 习惯用法,没有其他事情发生,我对此感到非常困惑。就好像在 iPad 上,除了 textView 之外的任何内容都没有设置,即使它们在 .xib 文件中正确链接。在 viewWillAppear 中,self.textView 在 iPad 上也按预期工作。我还尝试在 viewDidLoad 中执行此操作,如果我没有记错的话,应该在 viewWillAppear 之前调用它,甚至在解雇:方法中也尝试这样做,但它们永远不可用。
我需要访问按钮框架的原因是 about 视图相对复杂并且无法自动重新定位其子视图。我唯一需要做的就是在 iPad 上更大的模态视图上使按钮更宽。
任何提示将不胜感激!
提前致谢。
After a long while I've finally started working with Objective-C again, on my only complete app so far. The goal is to eventually refactor for ARC and possibly storyboards, but for the time being I'm polishing the iOS 4.x target. I am quite rusty, so bar with me if this is a stupid question.
I have a button in my main view that triggers the showAction method. The method is as follows:
- (void)showAbout
{
AboutViewController *aboutView = [[[AboutViewController alloc] init] autorelease];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
aboutView.modalPresentationStyle = UIModalPresentationFormSheet;
}
else
{
aboutView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
}
[self presentModalViewController:aboutView animated:YES];
}
The AboutViewController class has this .h:
@interface AboutViewController : UIViewController <UIActionSheetDelegate, MFMailComposeViewControllerDelegate> {
}
- (IBAction)dismiss:(UIButton *)sender;
- (IBAction)feedback:(UIButton *)sender;
@property (retain) IBOutlet UIButton *dismissButton;
@property (retain) IBOutlet UIButton *feedbackButton;
@property (retain) IBOutlet UIImageView *background;
@property (retain) IBOutlet UITextView *textView;
@end
and everything has been connected properly in the .xib file (the same one for iPhone and iPad). The actions are triggered as expected, and the outlets are accessible, but only on iPhone. When running on iPad, only textView is properly initialized, and all the rest points to nil.
In the .m I have tried this:
@implementation AboutViewController
@synthesize dismissButton = _dismissButton;
@synthesize feedbackButton = _feedbackButton;
@synthesize background = _background;
@synthesize textView = _textView;
// ...
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"obj self.dismiss: %@", self.dismissButton);
NSLog(@"frame dismiss: %@", NSStringFromCGRect(self.dismissButton.frame));
}
On iPhone I get this:
2012-02-08 22:51:00.341 myapp[17290:207] obj self.dismiss: <UIButton: 0x70281d0; frame = (180 410; 120 30); opaque = NO; autoresize = LM+W+RM+TM; layer = <CALayer: 0x7028260>>
2012-02-08 22:51:00.342 myapp[17290:207] frame dismiss: {{180, 410}, {120, 30}}
On iPad, instead, I get this:
2012-02-08 22:51:40.428 myapp[17320:207] obj self.dismiss: (null)
2012-02-08 22:51:40.428 myapp[17320:207] frame dismiss: {{0, 0}, {0, 0}}
There is nothing else that happens depending on the UI Idiom, and I'm really confused about this. It's as if on the iPad the outlets for anything other than textView are not set, even though they are correctly linked up in the .xib file. In viewWillAppear, self.textView is working as expected also on iPad. I also tried doing this in viewDidLoad, which should be called before viewWillAppear if I'm not mistaken, and even in the dismiss: method, but they are just never available.
The reason I need to access the buttons' frames is that the about view is relatively complex and fails to reposition its subviews automatically. The only thing I need to do is make the buttons wider on the larger modal view on iPad.
Any hints would be greatly appreciated!
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您曾经有过适用于 iPad 和 iPhone 的单独 .xibs 吗?如果是这样,您可能会遇到与我相同的问题。直到@AliSoftware向我透露了一些知识:
UIView 在 iPad 上是 nil,在 iPhone 上不是 nil
本质上你需要:
我相信问题是一个幽灵iPad 版 .xib 徘徊导致出现问题。真正将应用程序清除干净就达到了目的。祝你好运!
Did you ever have a separate .xibs for iPad and iPhone? If so you might have the same issue I had. That is until @AliSoftware dropped some knowledge on me:
UIView in nib is nil on iPad, and not nil on iPhone
Essentially you need to:
I believe the problem is that a ghost .xib for iPad was hanging around causing issues. Truly wiping the apps clean did the trick. Good luck!