【问题标题】:Reference the class that a subview was added from引用从中添加子视图的类
【发布时间】:2011-08-15 16:19:57
【问题描述】:

我正在向我的主 iPad UIViewController 添加一个子视图,并且在该子视图中我需要引用所述视图控制器才能使用该控制器播放视频。

任何人都可以帮助我完成应该做的方式,可能还有代码示例吗?

提前谢谢你。

问候,

埃德

编辑(更多信息):

这个子视图是来自为 iPhone 设计的 uiviewcontroller 类的视图。这是一个在按下一行时加载视频的表格。电影播放器​​在引用的视图控制器中加载视频(这就是我想从子视图中引用 iPad 视图控制器的原因)。该视图基本上以相同的形式在 iPad 应用程序中使用。

【问题讨论】:

    标签: iphone objective-c ios uiviewcontroller subview


    【解决方案1】:

    这听起来像是架构问题。告诉某些东西来播放声音并不取决于您的观点。那是管制员的工作。告诉“某人”它被触摸、滑动或用户所做的任何事情都取决于您的观点。 “某人”(正在观看的人)将对此做出正确的回应。

    为此,您的视图通常应该有一个目标,并可能采取行动。查看UIControl(例如UIButton)如何通知其他对象它已被激活。观察者(控制器)然后做出相应的反应。

    编辑

    视图不应加载视频。视图控制器应该加载视频并将其安装到正确的视图中。视图唯一的工作就是告诉它的视图控制器它已经被按下了。 UITableView 使用 UITableViewDelegate 方法 tableView:didSelectRowAtIndexPath: 自动处理此问题。如果您没有使用UITableView,您仍应遵循此模式。视图接受有一个委托,并告诉委托(控制器)选择了某些东西。然后控制器用新数据更新视图。

    【讨论】:

    • 嗨 Rob,我已经添加到我的问题中。这是否更有意义?
    • 您好 Rob,感谢您的编辑。我知道,该表位于 UIViewController 中,其中包含所有方法。但很明显,当我引用要在 iPad 上显示的视图时,没有视图控制器来显示视频(仅播放声音)。
    • 我不明白这是什么意思。你是什​​么意思“显然......没有视图控制器来显示视频?”这听起来一点也不明显。你在混合“视图”和“视图控制器”吗?我不明白你在这里的意思是什么类。我不知道“只有声音播放”是什么意思。这是你想要的,还是正在发生的事情?你在使用 MPMoviePlayer 吗?
    • 嗨,Rob,抱歉!行。我有 UIViewController,里面有一个相关的笔尖和视图。这用于应用程序的 iPhone 版本。在我的 iPad 视图控制器中,我将来自 iPhone 应用程序的视图添加为子视图。在 iPhone UIViewController 中,tableview didSelectRow 方法使用 MPMoviePlayer 加载正确的视频,传入 viewcontroller 作为参数来定义在其中播放视频的位置。我可以听到背景声音,但没有视频。
    • 您的问题很可能是nil。检查viewController 参数、view、任何 IBOutlets 等是否不是nil。特别要记住,在调用 viewDidLoad 之前,您的任何 IBOutlets 都不会设置。您可能想从一个更清晰的新问题重新开始。
    【解决方案2】:

    您可能已经在应用程序委托的属性中拥有主视图(它通常通过应用程序的 .xib 文件分配,查看应用程序委托的 applicationDidFinishLaunching: 方法,它将主视图作为子视图添加到窗口,类似于:

    [window addSubview:primaryController.view];
    [window makeKeyAndVisible];
    

    )。

    因此,您可以在应用中需要访问主视图的任何位置执行以下操作:

    [(MyAppDelegateType*)([UIApplication sharedApplication].delegate).primaryController somePrimaryControllerMethod];
    

    编辑:虽然这可行,但我同意 Rob Napier 的观点,即从架构角度来说,这不是最好的方法。

    【讨论】:

    • 不要尝试使用应用委托与其他视图控制器会合。这使得代码很难重用。如果你曾经重新排列你的 UI(添加一个标签控制器),整个技术就会崩溃。
    • 嗯,这取决于。主视图控制器通常不是一个普通的 UIViewController,而是一个特定于应用程序的子类。因此,只要您只调用自己编写的方法(例如 playMyCoolVideo),您就可以轻松地将主控制器替换为另一个(例如 iPad 版本)。
    • 问题是通过应用程序委托的钩子。应用程序委托不是全局变量的全球垃圾场。如果您需要与特定的相关视图控制器会合,请将视图控制器设为单例,而不是应用程序委托属性。将它放在应用程序委托中,以后很难更改 UI 架构,也很难将这些视图控制器移动到另一个项目中。
    • 这并不完全是一个垃圾场,因为主视图控制器是一个相当独特的东西(我相信相应的应用程序委托属性实际上是使用新的应用程序存根自动生成的)。但我明白你的意思,我已经编辑了我的答案以反映这一点。
    • 感谢大家的帮助。就我现在的设置方式而言,这对我来说是最好的选择。
    【解决方案3】:

    您可以使用[yourSubview superview] 来获取超级视图。

    【讨论】:

    • OP 正在寻找视图控制器,而不是视图。
    【解决方案4】:

    你不能像这样向视图添加一个属性:

    @property (nonatomic, assign) UIViewController *parentViewController;
    

    在视图初始化时(从 UIViewController 中),设置属性:

    UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 460.0f)];
    customView.parentViewController = self;
    

    从那时起,您应该能够从视图中调用 parentViewController。

    编辑: Rob Napier 有一个很好的观点,从视图中而不是视图控制器中设置目标和选择器可能是一个更好的主意。这样,您应该能够直接将方法与视图挂钩。属性如下所示:

    @property (nonatomic assign) id target;
    @property (nonatmic, assign) SEL selector;
    

    也许在你的视图中添加一个指定的初始化器:

    - (id)initWithFrame:(CGRect)aFrame target:(id)aTarget selector:(SEL)aSelector
    {
       self = [super initWithFrame:aFrame];
       if (self)
       {
          self.target = aTarget;
          self.selector = aSelector;
       }
       return self;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多