在我的iOS应用中,部分内容是视频播放器(使用YouTube API)。我决定使用滚动视图在代码中布局此视图,以确保在所有轮换中在应用程序的iPad版本中正确布局视图。在继续之前,这是我的子视图布局代码。每当我的观点出现在屏幕上时,我都会打电话。
- (void)setupView {
// Set up Open in YouTube App button
self.openInYouTubeAppButton = [[UIBarButtonItem alloc] initWithTitle:@"Open in YouTube App" style:UIBarButtonItemStylePlain target:self action:@selector(openInYouTubeApp)];
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"youtube://"]]) {
self.navigationItem.rightBarButtonItems = @[self.shareButton, self.openInYouTubeAppButton];
} else {
self.navigationItem.rightBarButtonItems = @[self.shareButton];
}
self.scrollView.frame = self.view.frame;
// Set up video embed view
self.videoEmbedView = ({
// Frame
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 768, 432)];
webView.center = CGPointMake(self.scrollView.center.x, (webView.bounds.size.height / 2));
// View Properties
webView.scrollView.contentInset = UIEdgeInsetsMake((-72 + 64), -8, 0, 0); // makes sure the video is fully seen in the view at first glance
webView.scrollView.scrollEnabled = NO; // doesn't allow the user to mistakenly scroll the video
webView;
});
self.videoTitleLabel = ({
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, (self.videoEmbedView.bounds.size.height + 14), 0, 0)]; // initial frame
label.text = self.videoTitle; // text is video title
label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; // dynamic type style
label.preferredMaxLayoutWidth = self.view.bounds.size.width; // makes sure label text does not extend outside the view.
[label sizeToFit];
label.center = CGPointMake(self.view.center.x, (self.videoEmbedView.bounds.size.height + 14 + (label.bounds.size.height / 2))); // set center
label;
});
self.videoDateLabel = ({
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8), 0, 0)]; // initial frame
label.text = [NSDateFormatter localizedStringFromDate:self.videoDate dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle];
label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; // dynamic type style
label.preferredMaxLayoutWidth = self.view.bounds.size.width; // makes sure label text does not extend outside the view.
[label sizeToFit];
label.center = CGPointMake(self.view.center.x, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + (label.bounds.size.height / 2))); // set center
label;
});
self.videoDescriptionTextView = ({
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + self.videoDateLabel.bounds.size.height + 25, 768, 200) textContainer:nil]; // initial frame
textView.text = self.videoDescription;
textView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
textView.center = CGPointMake(self.view.center.x, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + self.videoDateLabel.bounds.size.height + 25 + (textView.bounds.size.height / 2))); // set center
textView;
});
// Update scroll view content size
[self.scrollView setContentSize:CGSizeMake(self.view.bounds.size.width, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + self.videoDateLabel.bounds.size.height + 25 + self.videoDescriptionTextView.bounds.size.height))];
// Add views to scroll view
[self.scrollView addSubview:self.videoEmbedView];
[self.scrollView addSubview:self.videoTitleLabel];
[self.scrollView addSubview:self.videoDateLabel];
[self.scrollView addSubview:self.videoDescriptionTextView];
// Set description text view frame to content size
CGRect frame = self.videoDescriptionTextView.frame;
frame.size.height = self.videoDescriptionTextView.contentSize.height;
self.videoDescriptionTextView.frame = frame;
// Update scroll view content size
[self.scrollView setContentSize:CGSizeMake(self.view.bounds.size.width, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + self.videoDateLabel.bounds.size.height + 25 + self.videoDescriptionTextView.bounds.size.height))];
// Load video into embed view
NSString *embed = [NSString stringWithFormat:@"<iframe width='%f' height='%f' src='http://www.youtube.com/embed/%@' frameborder='0' allowfullscreen></iframe>", 768.0, 432.0, self.videoID];
[self.videoEmbedView loadHTMLString:embed baseURL:self.videoURL];
}
此代码在纵向方向上工作正常(但是,有一个错误,即动态设置文本视图的描述大小以适应内容;我也可以使用它的帮助)。
然后在旋转到横向(或者在景观中启动视图时),我想我需要编辑我的子视图位置;像这样(我被告知这是覆盖自转的最佳方法;它产生与自动旋转定制的所有其他方式相同的结果):
- (void)viewWillLayoutSubviews {
CGFloat screenHeight =[UIScreen mainScreen].bounds.size.height;
CGFloat screenWidth =[UIScreen mainScreen].bounds.size.width;
self.scrollView.frame = CGRectMake(0, 0, screenWidth, screenHeight);
[self.scrollView setContentSize:CGSizeMake(self.view.bounds.size.width, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + self.videoDateLabel.bounds.size.height + 25 + self.videoDescriptionTextView.bounds.size.height))];
// Scroll view subviews
self.videoEmbedView.center = CGPointMake(self.scrollView.center.x, (self.videoEmbedView.bounds.size.height / 2));
self.videoTitleLabel.center = CGPointMake(self.view.center.x, (self.videoEmbedView.bounds.size.height + 14 + (self.videoTitleLabel.bounds.size.height / 2)));
self.videoDateLabel.center = CGPointMake(self.view.center.x, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + (self.videoDateLabel.bounds.size.height / 2)));
self.videoDescriptionTextView.center = CGPointMake(self.view.center.x, (self.videoEmbedView.bounds.size.height + 14 + self.videoTitleLabel.bounds.size.height + 8 + self.videoDateLabel.bounds.size.height + 25 + (self.videoDescriptionTextView.bounds.size.height / 2)));
}
但这并不像我希望的那样好,我希望一切都是中心合理的,甚至是风景,但我得到了这个:
正如你所看到的,这些观点坚持他们以前的立场,并出现在他们的新职位上;并且视频嵌入视图根本不移动!
有人能帮助我吗?我卡住了,我到处寻找关于自动旋转中UIScrollView子视图的一般指导,所以现在我觉得是时候得到一些具体的答案了解我的情况。在此先感谢您的帮助。
答案 0 :(得分:1)
这个问题没有一个简单的“修复这行代码”。根据我的经验,滚动视图中的这种旋转大小调整最好通过使用自动布局来对UIScrollView中的视图进行排序,并使用自动布局根据滚动视图的容器调整大小。
从您的代码中看起来您已经拥有了这种视图结构:
UIScrollView (a)
UIWebView (b)
UILabel (c)
UILabel (d)
UILabel (e)
etc.
我会创建一个稍微不同的结构:
UIView (Z)
UIScrollView (a)
UIWebView (b)
UILabel (c)
UILabel (d)
UILabel (e)
etc.
使用自动布局语法我会做这些约束:H:| [Z] |和V:| [Z] |和H:| [a] |和V:| [a] | 有了这些,容器UIView和UIScrollView将始终填充他们分配的空间。 然后我会做的内容是: 五:| [B] [C] [d] [E] | H:|并[b] H:| [C] H:| [d] H:| [E] 您可能希望将“a”的大小设置为固定高度以适应视频,但是一旦您这样做,其余视图将以高度方式流动。水平轴约束,例如H:| [a]告诉自动布局所有视图都固定在UIScrollView(它们的父级)的前沿。
下一部分无法用自动布局可视化格式语言真正表达,但您所做的是创建约束,使得UIScrollView(b,c,d和e)中每个视图的宽度相同宽度为容器UIView(Z)。
当自动布局完成它的布局魔术时,它将使用内容的固有高度垂直布局视图,并使用容器的宽度来水平调整大小。