2

我已经设置了一个基本的测试应用程序,它显示一个包含标签的视图,不使用 IB。我想使用自定义 UIView 子类和自定义 UIViewController 子类。

这将按预期运行,但 MyViewController 的 viewWillAppear 和其他类似的委托不会触发。

我缺少什么来制造这些火?在以前的项目中(使用 IB),这些会很好。

这是完整的代码:

AppDelegate - 加载一个“MainVC”视图控制器并将其设置为根控制器

#import "AppDelegate.h"
#import "MainVC.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize mainVC = _mainVC;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.mainVC = [[MainVC alloc] init];
    self.window.rootViewController = self.mainVC;
    [self.window makeKeyAndVisible];
    return YES;
}

MainVC - 创建一个分配“MyView”的“MyViewController”(它还传递应该用于视图的帧大小)

#import "MainVC.h"
#import "MyViewController.h"

@implementation MainVC

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        MyViewController *controller = [[MyViewController alloc] init];
        CGRect frame;
        frame.origin.x = 5;
        frame.origin.y = 5;
        frame.size.width = self.view.frame.size.width - (2 * 5);
        frame.size.height = self.view.frame.size.height - (2 * 5);
        controller.startingFrame = frame;
        [self.view addSubview:controller.view];
    }
    return self;
}

MyViewController - 创建 MyView

#import "MyViewController.h"
#import "MyView.h"

@implementation MyViewController

@synthesize startingFrame;

- (void)loadView{
    self.view = [[MyView alloc] initWithFrame:startingFrame];
}

- (void)viewWillAppear:(BOOL)animated{
    NSLog(@"appearing"); //doesn't do anything
}

- (void)viewDidAppear:(BOOL)animated{
    NSLog(@"appeared"); //doesn't do anything
}

我的观点

#import "MyView.h"

@implementation MyView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        label = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 150, 40)];
        [label setText:@"Label"];
        [self addSubview:label];
    }
    return self;
}
4

3 回答 3

3

您的错误:您正在设置一个根视图控制器,然后在其上添加另一个视图控制器视图。当第二个视图添加到视图层次结构中时,它的视图控制器以这种方式保持“未连接”。事实上,如果你检查 MainViewController 的 parentViewController,你会注意到它是nil.

原因:presentModalViewController:animated: viewWillAppear 方法将仅发送到根视图控制器或根视图控制器层次结构中的视图控制器(使用或呈现的那些presentViewController:animated:completion:)。

解决方案:要解决它,您有几个选择:

  1. 使用您的视图控制器作为根视图控制器
  2. 通过上述方法之一展示您的视图控制器
  3. 保持您的代码原样并手动将这些事件连接到子视图控制器(但请注意这种方法,因为我相信您提到的事件会在 iOS 5 下自动转发 - 您可以轻松检查这一点)。
  4. 如果我记得正确,使这些事件转发到您的视图控制器的另一种方法是将您的视图控制器的视图添加到窗口,而不是父视图。
于 2012-05-29T15:26:01.680 回答
2

有许多非常基本的事情出错了:

  • 您正在initWithNibNamed:为 MainViewController 进行整个设置,但您正在创建它只是调用init. 所以你的设置永远不会发生
  • 您正在实现第二个 VC (MyViewController),显然只是为了创建 myView,然后将其添加到您的 rootVCs 层次结构中。不好!只有一个 VC(在您的情况下为 MainViewController)应该负责创建和管理其层次结构中的视图
  • 不要loadView像在 MyViewController 中那样设置 VC 控制器。在您的情况下,这是使事情正常进行的唯一方法,因为 MyVC 从未真正完全启动并运行,但方法是错误的 - 您基本上是在强制 View Controller 设置视图,尽管控制器本身从未在控制任何事物

还有一些东西,但这些是最重要的 - 看起来对您来说,再次阅读模型 - 视图 - 控制器概念的整个基本概念是一个好主意。接下来,您应该深入研究UIViewControllerUIView的类引用。

即使您最终会使用当前的方法获得您想要的结果,但从长远来看它对您没有帮助,因为您不会学会正确使用所涉及的元素。

于 2012-05-29T15:52:18.287 回答
0

方法不会在另一个视图控制器内的视图控制器上调用。如果仅针对iOS 5进行开发,请查看可用于解决此问题的UIViewController Containment 。如果您希望您的应用程序与以前的 iOS 版本兼容,您可以将方法调用转发到您的子视图控制器。就我个人而言,我更喜欢子类化 SFContainerViewController来自动处理这个问题:https ://github.com/krzysztofzablocki/SFContainerViewController

于 2012-06-04T18:08:06.973 回答