【发布时间】:2014-10-01 18:15:57
【问题描述】:
我正在努力解决一个我根本不明白的问题。这是以下场景:
- 我尝试在 iOS 中创建一个多视图向导。经过深思熟虑,我决定采用一种可能并不理想但能帮助我保持代码整洁的方法。我不想链接十个视图控制器并手动管理。
- 向导有一个视图控制器。在开始时,它会将一定数量的 UIView 加载到视图中,并允许我左右滚动。代码如下。
- UIViews 是在界面生成器中创建的,我有一个包含所有视图的 XIB 文件。
- 每个 UIView 都有更多连接到文件所有者的 IBOutlets(例如标签),在本例中为向导视图控制器。
除了加载的 UIViews 上的标签不更新这一事实之外,这一切都非常有效。问题来了:
- 我调用向导,它会立即加载所有 UIView 和 Outlets
- 我跳过向导。
-
然后问题就出现了:
- 示例:
- 第 2 步有一个调用通讯录的按钮(有效)
- 地址簿打开,返回一个对象(有效)
- 但是当我分配一个值时,我在 UIView“步骤 2”上的标签没有更新。
只有在我从向导中删除此 UIView 并将其重新添加后,它才能工作。在我看来, UIView 加载正确,但对其插座的任何后续更改都不起作用。
顺便说一句,我验证了标签以及按钮和所有内容可能都已连接。当标签作为 XIB 的一部分加载时,我只是无法更新标签,并且在初始加载后值会发生变化。
代码:
向导加载 UIViews:
-(void)configureWizard
{
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.scrollEnabled = NO;
self.contentSize = CGSizeMake(CGRectGetWidth(self.frame) * [wizardDelegate numberOfSteps], CGRectGetHeight(self.frame));
self.delegate = self;
}
-(void)loadWizard
{
[self configureWizard];
[self updateNavButtonsIfNecessary];
currentIndex = 0;
for (int i = 0; i<[wizardDelegate numberOfSteps]; i++)
{
[self loadWizardStepAtIndex:i];
}
}
- (void)loadWizardStepAtIndex:(int)index {
CGRect frame = self.frame;
frame.origin.x = CGRectGetWidth(frame) * index;
frame.origin.y = 0;
UIView *view = [wizardDelegate viewForStepAtIndex:index];
view.frame = frame;
[self addSubview:view];
}
向导主视图 Controller.h(文件所有者)
@property (strong, nonatomic) IBOutlet UIView *memberwizard_1;
@property (strong, nonatomic) IBOutlet UIView *memberwizard_2;
@property (strong, nonatomic) IBOutlet UIView *memberwizard_3;
@property (strong, nonatomic) IBOutlet UIView *memberwizard_4;
@property (strong, nonatomic) IBOutlet UIView *memberwizard_5;
@property (strong, nonatomic) IBOutlet UIView *memberwizard_6;
@property (strong, nonatomic) IBOutlet UIView *memberwizard_7;
@property (strong, nonatomic) IBOutlet UIButton *wizard2_lookupExistingContact;
@property (strong, nonatomic) IBOutlet UILabel *wizard2_nameLabel;
向导主视图 Controller.m(文件所有者)
-(UIView *)viewForStepAtIndex:(int)index
{
[[[NSBundle mainBundle]loadNibNamed:@"wizard_newMember" owner:self options:nil] lastObject];;
switch (index) {
case 0:
return self.memberwizard_1;
break;
case 1:
return self.memberwizard_2;
break;
case 2:
return self.memberwizard_3;
break;
case 3:
return self.memberwizard_4;
break;
case 4:
return self.memberwizard_5;
break;
case 5:
return self.memberwizard_6;
break;
case 6:
return self.memberwizard_7;
break;
default:
return self.memberwizard_1;
}
}
通讯录返回函数
-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person
{
[self displayPersonRecord:person];
[self dismissViewControllerAnimated:YES completion:nil];
}
尝试更新第二个 UIView 上的标签(这是出现问题的地方 - 它不起作用)。
-(void) displayPersonRecord:(ABRecordRef)person
{
NSString *firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSLog(@"Name is %@", [NSString stringWithFormat:@"%@ %@", firstName, lastName]);
self.wizard2_nameLabel.text = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
[self.wizardDelegate refresh:self.memberwizard_2]; //if called, the current view will be removed and re-added - then the label gets updated.
}
但正如我提到的,如果我重新加载视图,它就会起作用(见截图)
重新加载方法 重要提示:这是讨厌的代码,不用于生产,它只是一个测试,看看重新加载视图是否有帮助。
-(void)refresh:(UIView *) oldView
{
[oldView removeFromSuperview];
CGRect frame = self.frame;
frame.origin.x = CGRectGetWidth(frame) * currentIndex;
frame.origin.y = 0;
//UIView *view = [wizardDelegate viewForStepAtIndex:currentIndex];
oldView.frame = frame;
[self addSubview:oldView];
}
如果此时我从向导中删除 self.memberwizard_2 视图并将其重新添加到一切正常,但它不会马上。这可能与我启动 UIViews 的方式有关吗?顺便说一句,最后一段中的 NSLog 也可以显示联系人的姓名。
如果有人知道处理向导的更简单方法,请告诉我:) PageViewControllers 很痛苦,因为我需要在屏幕之间切换一个对象,但需要在每个屏幕中显示不同的操作。
非常感谢并为代码混乱道歉,我试图让它尽可能清晰,但也许不是。
【问题讨论】:
-
[self.wizardDelegate refresh:[self.memberwizard_2];这里的左括号和右括号的数量不一样。首先,尝试解决此问题。[self.wizardDelegate refresh:self.memberwizard_2]; -
感谢您的评论,但这是一个错字(或复制粘贴错误)。但这不是问题,因为我实际上不想使用这种刷新方法。我想弄清楚为什么标签一开始没有更新
-
您是否尝试过使用调试器单步执行您的代码?
-
在将新字符串分配给标签之前,如果使用
NSLog(@"Object: %@, View: %@, Subviews: %@, Label: %@", self, self.memberwizard_2, self.view.subviews, self.wizard2_nameLabel),您会看到什么? -
尝试 awakeFromNib 而不是在
-(UIView *)viewForStepAtIndex:(int)index中加载它。因为视图已经加载。不要加载另一个。
标签: ios objective-c uiview xib