ChatGPT解决这个技术问题 Extra ChatGPT

如何将 UIViewController 的视图添加为子视图

谷歌员工请注意,这个 QA 现在已经过时六年了!

正如下面的 Micky 和其他人所提到的,现在在 iOS 中每天都使用 Containers 来完成这项工作。

我有一个控制许多子视图的 ViewController。当我单击其中一个按钮时,我会初始化另一个视图控制器并将其视图显示为该视图的子视图。然而,子视图超出了子视图的框架边界,实际上填满了整个屏幕。

有什么问题?我认为问题在于 UIViewController 的视图有一个框架 (0,0,320,460),因此会填满整个屏幕(尽管它仅在子视图框架范围内触摸时才会接收触摸事件)。如何调整框架大小以适合子视图。

简而言之,我需要帮助将视图控制器的视图作为子视图添加到另一个视图控制器的视图中。

谢谢!

我建议不要这样做。我为我的第一个 iPhone 应用程序做了这个,结果发现它是一个巨大的奇怪的混乱,更不用说它破坏了我试图用 Interface Builder 做的很多事情。在 3.0 文档中,他们特别说 - 每个屏幕 1 个视图控制器。你应该做这个!
是的,即使我读过它,但问题是,如果我把它全部放在 1 个视图控制器中,它就会将大量代码放入 1 中,并且有很多 IBOutlets 和操作以及表格。因此,为了清晰和模块化,我尝试使用 2 个单独的视图控制器,第二个只是为主视图控制器提供视图并处理它自己的事件。这样主视图控制器就更干净了。我应该怎么做。我应该有多个带有导航控制器的视图控制器还是 1 个巨大的视图控制器。
看看这个tutorial。它只是部分有效

C
Cœur

As of iOS 5,Apple 现在允许您制作 custom containers,以便将 UIViewController 添加到另一个 UIViewController,特别是通过 addChildViewController 等方法,因此确实可以嵌套 UIViewControllers

编辑:包括就地摘要以避免链接损坏

我引用:

iOS 提供了许多标准容器来帮助您组织应用程序。但是,有时您需要创建一个与任何系统容器提供的工作流都不匹配的自定义工作流。也许在您的设想中,您的应用程序需要一个特定的子视图控制器组织,它们之间具有专门的导航手势或动画转换。为此,您需要实现一个自定义容器 - 告诉我更多...

...和:

当你设计一个容器时,你在你的容器、父级和其他视图控制器、它的子级之间创建了明确的父子关系——告诉我更多

示例(由 Apple 文档提供)将另一个视图控制器的视图添加到容器的视图层次结构中

- (void) displayContentController: (UIViewController*) content
{
   [self addChildViewController:content];                 
   content.view.frame = [self frameForContentController]; 
   [self.view addSubview:self.currentClientView];
   [content didMoveToParentViewController:self];          
}

在我的答案顶部添加了评论。
你确定这是iOS 5?我在使用 iOS 5 时遇到了崩溃,但在 iOS 6 中运行良好。
iOS 5,我们在我们的应用程序中使用它
谢谢米奇。事实证明,iOS 5 不支持的只是故事板嵌入 segue。
currentClientView 的作用是什么?我在文档中根本无法理解。
W
WIll Cobb

多亏了这些人,我做到了http://highoncoding.com/Articles/848_Creating_iPad_Dashboard_Using_UIViewController_Containment.aspx

添加 UIView,将其连接到标题:

@property (weak, nonatomic) IBOutlet UIView *addViewToAddPlot;

在 - (void)viewDidLoad 中这样做:

ViewControllerToAdd *nonSystemsController = [[ViewControllerToAdd alloc] initWithNibName:@"ViewControllerToAdd" bundle:nil];
    nonSystemsController.view.frame = self.addViewToAddPlot.bounds;
    [self.addViewToAddPlot addSubview:nonSystemsController.view];
    [self addChildViewController:nonSystemsController];
    [nonSystemsController didMoveToParentViewController:self];

享受


文档声明 didMoveToParentViewController 应该在 addChildViewController 之后调用,而不是之前。
谢谢...很好的解决方案!
S
Steven Fisher

这个答案对于旧版本的 iOS 是正确的,但现在已经过时了。您应该使用 Micky Duncan 的答案,其中涵盖了自定义容器。

不要这样做! UIViewController 的目的是驱动整个屏幕。它只是不适合这个,它并没有真正添加你需要的任何东西。

您所需要的只是一个拥有您的自定义视图的对象。只需使用 UIView 本身的子类,它就可以添加到您的窗口层次结构中,并且内存管理是全自动的。

将子视图 NIB 的所有者指向 UIView 的自定义子类。向这个自定义子类添加一个 contentView 出口,并将其指向笔尖内的视图。在自定义子类中执行以下操作:

- (id)initWithFrame: (CGRect)inFrame;
{
    if ( (self = [super initWithFrame: inFrame]) ) {
        [[NSBundle mainBundle] loadNibNamed: @"NibNameHere"
                                      owner: self
                                    options: nil];
        contentView.size = inFrame.size;
        // do extra loading here
        [self addSubview: contentView];
    }
    return self;
}

- (void)dealloc;
{
    self.contentView = nil;
    // additional release here
    [super dealloc];
}

(我在这里假设您使用 initWithFrame: 来构造子视图。)


虽然当时是一个很好的答案,但这可能是自 iOS 5 以来过时的哲学。请参阅下面的答案
确实,这是几年前写的。我还没有使用自定义容器,但这似乎是解决这个问题的正确方法。
感谢我回答史蒂文的插件:)
L
Logan

我觉得所有这些答案都有些不完整,所以这是将 viewController 的视图添加为另一个 viewController 视图的子视图的正确方法:

    [self addChildViewController:viewControllerToAdd];
    [self.view addSubview:viewControllerToAdd.view];
    [viewControllerToAdd didMoveToParentViewController:self];

如果您愿意,可以将其作为片段复制到您的代码中。 SO 似乎不理解代码替换格式,但它们会在 Xcode 中显示干净:

    [self addChildViewController:<#viewControllerToAdd#>];
    [self.view addSubview:<#viewControllerToAdd#>.view];
    [<#viewControllerToAdd#> didMoveToParentViewController:self];

willMove 使用 addChild 自动调用。谢谢@iOSSergey

当您的自定义容器调用 addChildViewController: 方法时,它会在添加视图控制器之前自动调用要添加为子视图控制器的 willMoveToParentViewController: 方法。


当您的自定义容器调用 addChildViewController: 方法时,它会在添加视图控制器之前自动调用要添加为子视图控制器的 willMoveToParentViewController: 方法。
@iOSergey 你有那个链接吗?很想更新答案以使其更正确。
实际上我也经常手动使用 willMoveToParent ,但是当我不小心读到苹果对这个函数的引用时,我感到很惊讶 :) developer.apple.com/library/ios/documentation/UIKit/Reference/…
@iOSergey - 对不起,也许我很密集,但我没有在那里看到它:) 请注意更具体地指点我!你不是一个人总是打电话,当人们不可避免地告诉我把它放回去时,我想有一个很好的参考!再次感谢!
在我链接的网站上搜索“willMoveToParentViewController”,展开“willMoveToParentViewController”参考并在讨论标题下最后一段:) 我发布了完整链接,但由于某种原因它重定向到顶部。
r
rptwsthi

利用:

[self.view addSubview:obj.view];

r
rptwsthi

更改 viewcontroller.view.frame 的帧大小,然后添加到子视图。 [viewcontrollerparent.view addSubview:viewcontroller.view]


我尝试过这个。它不起作用。我应该在界面生成器中做些什么吗?
b
bolek

您必须设置边界属性以适合该框架。 frame 其 superview 属性,并且 bounds 将 frame 限制在 view 本身的坐标系中。


A
Anjali jariwala

您可以将 PopupController 用于将 UIViewController 显示为子视图的 SDK 您可以检查 PopupController

这是相同的示例代码

popup = PopupController
        .create(self.navigationController!)
        .customize(
            [
                .layout(.center),
                .animation(.fadeIn),
                .backgroundStyle(.blackFilter(alpha: 0.8)),
                .dismissWhenTaps(true),
                .scrollable(true)
            ]
        )
        .didShowHandler { popup in
        }
        .didCloseHandler { popup in
    }
    let container = MTMPlayerAndCardSelectionVC.instance()
    container.closeHandler = {() in
        self.popup.dismiss()
    }

    popup.show(container)

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅