【问题标题】:UIScrollView breaking when a new subview added添加新子视图时 UIScrollView 中断
【发布时间】:2012-10-25 07:06:17
【问题描述】:

总的来说,我对 iOS 平台和目标 C 的编码还很陌生。我正在使用情节提要编写一个简单的 iPhone 应用程序,该情节提要具有通过嵌入 UIScrollView 的 UIImageView 显示的高 png 文件以及旁边的一个按钮来播放电影。

我的问题是,当电影结束/退出并返回到原始屏幕时,UIScrollView 内的滚动不起作用。我已经确定了“原因”。当我将 MPMoviePlayerViewController object.view 添加到 self.view 子视图时会发生这种情况。但我不确定如何纠正这个问题。这是我的提炼代码:

.h 文件

@interface StuffViewController : UIViewController 

@property (strong,nonatomic) IBOutlet UIImageView *imageView;
@property (strong,nonatomic) IBOutlet UIScrollView *scrollView;

-(IBAction) playMovie;
-(void) moviePlayBackDidFinish:(NSNotification*)notification;

@end

.m 文件

-(void) viewDidLoad {
    self.imageView.image = [UIImage imageNamed:@"image.png"];
}

-(void) viewDidAppear:(BOOL)animated {
    self.scrollView.contentSize = self.imageView.image.size;
}

-(void) playMovie {
    NSURL *movieURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                         pathForResource:@"movieTitle" ofType:@"mp4"]];
    MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc] 
                                                initWithContentURL:movieURL];
       [[NSNotificationCenter defaultCenter] addObserver:self
                                        selector:@selector(moviePlayBackDidFinish:)
                                            name:MPMoviePlayerPlaybackDidFinishNotification
                                          object:moviePlayer];
    [moviePlayer setMovieSourceType:MPMovieSourceTypeFile];
    [[self view] addSubview:moviePlayer.view];   //SCROLLING BREAKS HERE
    [moviePlayer setFullscreen:YES];
    [moviePlayer play];
}

-(void)moviePlayBackDidFinish: (NSNotification*)notification {
    MPMoviePlayerController *movieDone = [notification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [movieDone.view removeFromSuperview];
    [movieDone setFullscreen:NO];
}

我通过注释掉部分确定了罪魁祸首,就像我说的那样,滚动“锁定”在“[[self view] addSubview:moviePlayer.view];”在我导航到不同的视图然后返回之前不会恢复。

我们将不胜感激任何和所有的帮助。

编辑:我发现了一个有趣的皱纹,可能有助于发现根本问题。

我一直在使用MPMoviePlayerController。然而,在切换到MPMoviePlayerViewController 之后,发生了一些有趣的事情。

这里是改变的 -(void)playMovie

-(void) playMovie {
   self.scrollView.contentOffset = CGPointZero;
   NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                    pathForResource:totalTitle ofType:@"mp4"]];
   MPMoviePlayerViewController *playerController =  [[MPMoviePlayerViewController alloc] initWithContentURL:url];
   [self presentMoviePlayerViewControllerAnimated:playerController];
   playerController.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
   [playerController.moviePlayer play];
   playerController = nil;
}

有趣的是 UIScrollView 仍然可以工作,但是,如果它已经向下滚动,它将不再能够从电影开始时的位置向上滚动。我通过在playMovie 的开头添加self.scrollView.contentOffset = CGPointZero 来解决此问题,以告诉scrollView 移动到顶部(因此它上面没有任何东西需要滚动回)。我假设在viewDidAppear 中的代码中添加某种 if 语句以防止 scrollView.contentSize 重新执行可能会解决无法向上滚动的问题,但是我喜欢它开始的“干净”回到顶部。

最后一期。像这样使用 MPMoviePlayerViewController 会导致在执行 MPMoviePlayerViewController *playerController = [[MPMoviePlayerViewController alloc] initWithContentURL:url]; 行时在我的调试器中弹出许多有趣的错误。它们如下:

Oct 25 10:25:51 Compy.local AppName[14590] <Error>: CGContextSaveGState: invalid context 0x0 
Oct 25 10:25:51 Compy.local AppName[14590] <Error>: CGContextClipToRect: invalid context 0x0
Oct 25 10:25:51 Compy.local AppName[14590] <Error>: CGContextTranslateCTM: invalid context 0x0
Oct 25 10:25:51 Compy.local AppName[14590] <Error>: CGContextDrawShading: invalid context 0x0
Oct 25 10:25:51 Compy.local AppName[14590] <Error>: CGContextRestoreGState: invalid context 0x0

它似乎没有破坏任何东西。然而,当涉及到错误的错误陈述时,我往往是一个完美主义者。我已经对这些错误进行了一些研究,但是我还没有找到任何合适的方法来应对这种情况。

感谢到目前为止的所有帮助!再一次,我也将不胜感激。

【问题讨论】:

  • 请在播放器完成视频播放时添加代码 :)
  • 根据 Sebastian 的要求进行了编辑以包含完成的电影代码

标签: xcode uiscrollview subview


【解决方案1】:

您确定所有内容都已从超级视图中删除吗?另外,您可以尝试替换

 MPMoviePlayerController *movieDone = [notification object];

 MPMoviePlayerController *movieDone = (MPMoviewPlayerController *)[notification object];

还有添加

movieDone = nil;

为确保您的 MPMoviePlayerController 已完全从 superView 中删除,请在视频播放完毕后尝试按下视图上的按钮(在添加 MPMoviePlayerController 之前创建)并查看它是否触发。导航控制器必须以模态方式呈现您的 MPMoviewPlayerController 或进行推送。如果它是以模态方式呈现的,请在播放完成后尝试将其关闭。

【讨论】:

  • 看到他的代码他既不是推动它也不是模态地添加它。它是滚动视图的子视图。所以我可能期望 MPMoviePlayer 的视图确实仍然在滚动视图之上。就像 Andrei 说的,检查电影播放器​​框架后面的按钮在关闭视图后是否仍然响应。
  • 很好的建议。 Andrei,我按照您的建议进行了更改,但是视频后滚动条仍处于锁定状态。更有趣的是,播放电影的按钮在播放完电影后仍然可以正常使用。
  • 我最终更改了 movieplayer 方法并将其附加到原始帖子以反映更改。它或多或少地解决了原来的问题,但出现了一组新的错误。
  • 视频播放结束后调用什么委托方法?似乎您的滚动视图的插图在播放后被修改。您可以在视频播放完毕后更改它,这样您就不必在播放视频之前一直滚动到顶部。此外,您可以在项目中搜索显示该错误的 nslog 并查看其中有什么问题...
  • 我相信我已经找到了电影播放后滚动无法正常工作的原始问题的原因。当我在情节提要中设置 ImageView 的大小时,它会在电影完成后滚动到该点。我的猜测是它忘记了图像的大小。我很好奇如何以编程方式“提醒” UIView。任何帮助将不胜感激。
【解决方案2】:

问题的原因是在 Storyboard 中使用了“自动布局”。我不是 100% 确定为什么它会在播放电影之后而不是之前导致它出现问题。但是我通过以下任一方式修复了它:

A:移除自动布局

B:使用约束函数直到它最终工作。 (将 UIImageView 的高度更改为 0 并将 Equals: Default 更改为尽可能低的优先级。)

【讨论】:

    【解决方案3】:

    尝试在moviePlayBackDidFinish 方法中将self 和/或self.scrollviewSetUserInteractionEnabled 设置为YES。 此外,检查滚动视图的 ContentSize 属性的大小,以检查大小是否大于您的实际屏幕大小,看看这是否导致滚动视图的功能中断。

    【讨论】:

    • 感谢您的回复。不幸的是,使用'self.scrollView.userInteractionEnabled = YES'并没有解决问题。插入断点并检查 scrollView.contentSize 变量后,它似乎在播放电影后具有适当的大小。
    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    相关资源
    最近更新 更多