我有一个基于横向的视图,里面有一个SKView(skView
)。我希望skView
的宽度始终为视图的100%,静态高度为288.我添加了一些约束但是当我在模拟器中启动应用程序时,它给了我相同的CGSize(568 x 288) ),无论我选择iPhone 4还是3.5。
- (void)viewDidLoad {
CGSize size = self.skView.bounds.size; // 568 x 288
...
}
我在这里缺少什么?
更新#1
一位用户建议我在self.skView.bounds.size
中看到viewWillAppear:
的价值,这会产生一些奇怪的结果(我不确定他们是否有帮助)
更新#2
删除所有约束并将它们重新添加为一个评论者(在我发布的github示例项目中更新)后,建议我现在有以下内容(尽管仍然破坏):
IB中的线条是蓝色的,我的意思是没有歧义,但它似乎仍然不起作用。
更新#3
从用户matt
收到新约束并使用viewWillAppear
代替viewDidLoad
后,问题似乎仍然普遍存在。似乎skView
的宽度永远不会符合view
正如您在屏幕截图中看到的那样,文字被截断,因为在3.5英寸iPhone上skView
的宽度仍然是568(iPhone 4英寸宽度的横向)。
答案 0 :(得分:6)
当您的视图配置代码启动时,听起来视图的约束尚未得到解决。也就是说,那时的帧与您使用自动布局约束创建的“真实”布局不对应(哪个应该适合skView
到view
。
我已将代码从viewWillAppear
移至viewDidLayoutSubviews
,结果发现,在布局过程的这个时候,view
和skView
的界限已经更新,它似乎适用于3.5“和4”屏幕。
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGSize skViewSize = self.skView.bounds.size;
SKScene *scene = [MyScene sceneWithSize:skViewSize];
scene.scaleMode = SKSceneScaleModeAspectFill;
[self.skView presentScene:scene];
}
This tutorial可能会对该主题有更多了解。
顺便说一句,我已经提交了一个拉取请求,我对您的示例存储库进行了更改,以便您可以浏览更改。
答案 1 :(得分:2)
viewWillAppear
和viewDidLoad
如果您的观看仅在创建视图时依赖于大小(例如代码中的presentScene),那么您最好在viewDidAppear
或“viewDidLayoutSubviews”中进行操作。
我已经在每个方法中尝试了您的代码(在评论viewWillAppear
之后)并且它按预期工作。
修改强>
我已将scaleMode
中的wiewWillAppear
从SKSceneScaleModeAspectFill
更改为SKSceneScaleModeFill
,并且效果也很好。
我认为这比仅在呈现视图控制器之后呈现场景更好。
答案 2 :(得分:2)
我认为有一种捷径方法.. 首先,你必须勾选文件检查器中的“使用自动布局”, 然后在界面构建器中显示四个按钮,1:对齐2:针脚3:重新启动自动布局问题和4:调整大小行为.. 现在选择任何对象,你想在横向和纵向模式下显示相同的对象, 然后单击第三个按钮(Reslove autolayout)..根据您的要求选择“在视图控制器中添加缺少约束”或“在视图中添加缺少约束”。
答案 3 :(得分:1)
这里有两个问题。
首先,你原来的限制是完全错误的;如果您还希望修正垂直高度,则不需要SKView顶部和底部的垂直空间!这两件事是彼此相反的。
其次,Xcode中存在一个错误。 :(您可以在第二组约束中看到它。顶部布局指南的顶部约束出错了(您可以从-288看到)。您不小心从顶部布局指南到< SKView的em> bottom (这是Xcode的错误,它可以帮到你)。以下是解决这个问题的方法:
删除顶部约束。
将SKView向下移动。
按住Control键并拖动以再次形成顶部布局指南的顶部约束。
现在选择顶部约束并手动将其常量设置为0,以使SKView再次向上移动。
结果将是:
SKView的高度限制为280。
视图(主视图)对SKView的前导和后续水平空间约束为0,从顶部布局指南到SKView的顶部约束为0(不是-288!)。
Bingo,现在一切都会正常工作。
答案 4 :(得分:0)
实际上我不知道正确的原因,但是调用了layoutIfNeeded
方法,之后会显示当前的大小。
[self.skView layoutIfNeeded];
CGSize size = self.skView.bounds.size;
答案 5 :(得分:0)
受@Michael Kessler的回答启发我做了一些实验。
在viewDidAppear
中,我记录了主视图,skView和场景的大小。
对于不同的scaleModes,这里是结果。
SKSceneScaleModeAspectFill
viewSize = {480,320}, skViewSize = {480,280}, sceneSize = {568,280}
SKSceneScaleModeFill
viewSize = {480,320}, skViewSize = {480,280}, sceneSize = {568,280}
SKSceneScaleModeResizeFill
viewSize = {480,320}, skViewSize = {480,280}, sceneSize = {480,280}
很明显,您想要的模式是 SKSceneScaleModeResizeFill ,以使场景大小与视图大小完全匹配。
但是你会注意到Hello,World仍然在屏幕的右侧。
原因是当SKScene初始化时设置SKLabel的位置,当场景大小不正确时,该位置在viewDidAppear
。
您可以在MyScene类中按如下方式重新定位它。调整SKScene的大小时,会调用此方法。
-(void)didChangeSize:(CGSize)oldSize {
_myLabel.position = CGPointMake(self.size.width, self.size.height/2.0);
}
注意:事情似乎适用于 SKSceneScaleModeFill ,但你所拥有的是一个宽度为568的场景,缩放到适合480而不是宽度为480的场景。