【问题标题】:New instance of a UIViewController within another UIViewController: Why can't I set an instance variable?另一个 UIViewController 中的 UIViewController 的新实例:为什么我不能设置实例变量?
【发布时间】:2011-09-23 05:28:37
【问题描述】:

所以我有一个名为 MyTabBarViewController 的 UIViewController 子类,它有一个 UIScrollView。在 MyTabBarViewController 内部,我正在创建另一个 UIViewController 子类的实例,称为 PhotoViewController。 (注意:我这样做是为了可以使用 IB 设置 IBOutlets)

我正在尝试从我的 TabBarViewController 中设置每个 PhotoViewController 实例的标签。我为每个 PhotoViewController 使用 nib 初始化,所以我的印象是每个 PhotoViewController 实例都将连接到它们各自的 IBOutlets - 允许我使用 pvc.label.text = @"text I want" 简单地设置标签名称。

你能解释一下为什么我的逻辑不正确吗?因为它不起作用,并且不确定该怎么做。 :-/

MyTabBarViewController.m

#import "MyTabBarViewController.h"


@implementation MyTabBarViewController
@synthesize pageControl,scroller;

-(IBAction)clickPageControl:(id)sender
{
    int page=pageControl.currentPage;
    CGRect frame=scroller.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    [scroller scrollRectToVisible:frame animated:YES];
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    int page = scrollView.contentOffset.x/scrollView.frame.size.width;
    pageControl.currentPage=page;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (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.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    scroller.delegate=self;
    scroller.pagingEnabled=YES;
    scroller.directionalLockEnabled=YES;
    scroller.showsHorizontalScrollIndicator=NO;
    scroller.showsVerticalScrollIndicator=NO;
    scroller.contentSize=CGSizeMake(pageControl.numberOfPages*scroller.frame.size.width, scroller.frame.size.height);
    CGFloat scrollWidth = 0;
    int pageNumber = 0;
    for (int i=0; i<3; i++)
    {
        PhotoViewController *pvc = [[PhotoViewController alloc] initWithNibName:@"PhotoViewController" bundle:nil];
        CGRect rect = scroller.frame;
        rect.size.height = scroller.frame.size.height;
        rect.size.width = scroller.frame.size.width;
        rect.origin.x = scroller.frame.origin.x + scrollWidth;
        rect.origin.y = scroller.frame.origin.y;
        pvc.label.text = [NSString stringWithFormat:@"%d", pageNumber];
        pvc.label.textColor = [UIColor redColor];
        pvc.view.frame  = rect;
        [scroller addSubview:pvc.view];
        [pvc release];
        pageNumber++;
        scrollWidth += scroller.frame.size.width;
    }
    pageControl.numberOfPages=3;
    pageControl.currentPage=0;
    [self.view addSubview:scroller];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

PhotoViewController.h 非常简单。 PhotoViewController.m 也是,但如果我的问题在那里,我已经包含了实现文件。

PhotoViewController.m

#import "PhotoViewController.h"


@implementation PhotoViewController
@synthesize label, imageView, sendButton, cancelButton;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)dealloc
{
    [super dealloc];
}

- (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.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

【问题讨论】:

    标签: iphone ios uiviewcontroller instance-variables


    【解决方案1】:

    您不能像这样设置任何与视图相关的值(制作对象并从该视图设置其他条目)。

    因为您不能在任何视图控制器的viewDidLoad 之前设置任何级别的值。您需要相应地为标签设置字符串类型的属性并在 MyTabBarViewController 中设置它们的值,然后从堆栈中获取对象PhotoViewController 中的 MyTabBarViewController 类,然后访问它的属性并设置标签。

    要从堆栈中选择视图对象,您需要使用这一行

    MyTabBarViewController *obj = (MyTabBarViewController *)[self.navigationController.viewControllers objectAtIndex: [self.navigationController.viewControllers count]-2];
    

    【讨论】:

    • 谢谢 Ishu :-) 我得到了你关于viewDidLoad 的答案的第一部分,但我对你答案的第二部分仍然有点不清楚。如何在 MyTabBarViewController 中设置值?如果稍后我想访问 PhotoViewController 的属性并设置标签,为什么我需要在 MyTabBarViewController 中设置值?我只是问,因为如果我稍后在 PhotoViewController 中设置它们,那么当我在 MyTabBarViewController 中设置值时,这听起来像是一个浪费的步骤。非常感谢 Isha 的初步反馈! :-)
    • 如果您在 MyTabBarViewController 中创建属性,那么答案的第二部分会有所帮助。如果你在 photoViewController 中创建属性,那么你不需要。我想我的答案中 MyTabBarViewController 类的属性。
    • 最健壮的方法是在每个 PhotoViewController 中设置独立的属性,以便从 viewDidLoad 中引用。 (如果您可以使用父类中的公共值,只需在子对象中设置父属性并使用它来引用父对象。)这涵盖了手机由于内存不足而在某些时候卸载视图控制器的微小机会.但是,如果您想忽略这种微小的可能性,只需在设置标签之前在子项中引用“视图”即可。
    • 是的,非常正确。需要在 PhotoViewController 中而不是在 MyTabBarViewController 中创建属性。
    • @Daniel 和@Ishu 非常感谢你们帮我解决这个问题。我去了 developer.apple 上的 UIVIewController 页面,以确保我正确理解了你们两个。提到的视图属性:如果你访问这个属性并且它的值当前是 nil,视图控制器会自动调用 loadView 方法并返回结果视图。默认的 loadView 方法尝试从与视图控制器(如果有)关联的 nib 文件中加载视图。 -- 我相信这就是你告诉我的,对吗?我在设置我的属性之前添加了[pvc view],一切正常。 :-)
    【解决方案2】:

    IBOutlet 实体在 viewDidLoad 之前不存在,并且通常在您启动节目之前不会发生。因此,在 MyTabBarViewController 中,您正在处理一个不存在的标签等。 (当然,Objective-C 很方便地忽略了对 nil 指针的调用,所以看起来一切正常——只是什么都没发生。)

    根据规范,可以通过引用视图控制器的视图属性来触发加载,但我从未尝试过。

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 2015-06-09
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多