有没有一种方法可以在 Interface Builder 中实际*视觉设计*双视​​图(横向 + 纵向)?

Posted

技术标签:

【中文标题】有没有一种方法可以在 Interface Builder 中实际*视觉设计*双视​​图(横向 + 纵向)?【英文标题】:Is there a method to actually *visually design* twin views (landscape + portrait) in Interface Builder? 【发布时间】:2011-03-03 13:05:19 【问题描述】:

我目前的设计要求在数据的纵向和横向视图之间使用一些很酷的动画。数据表示相当复杂,因此在图形和数据元素之间,屏幕上可能同时有大约 30 个按钮和标签。我创建了一个设计非常紧凑的界面……现在我正在为横向视图布置元素。到目前为止,我发现这样做的唯一方法是在代码中实际布置横向视图,例如:

-(void) positionViews 
    UIInterfaceOrientation destOrientation = self.interfaceOrientation;
    if (destOrientation == UIInterfaceOrientationPortrait || destOrientation == UIInterfaceOrientationPortraitUpsideDown) 
        //---if rotating into PORTRAIT mode
        timeBGbox.frame = CGRectMake(14, 88, 134, 14);
        targetTime.frame = CGRectMake(0, 99, 150, 29);
        energyBGbox.frame = CGRectMake(156, 88, 68, 14);
        targetEnergy.frame = CGRectMake(154, 99, 70, 29);
        speedBGbox.frame = CGRectMake(234, 88, 68, 14);
        targetSpeed.frame = CGRectMake(226, 99, 48, 29);
        speedLabel.frame = CGRectMake(264, 99, 40, 36);
     else 
        //---if rotating to LANDSCAPE mode
        timeBGbox.frame = CGRectMake(156, 12, 152, 14);
        targetTime.frame = CGRectMake(160, 23, 150, 29);
        energyBGbox.frame = CGRectMake(156, 50, 68, 14);
        targetEnergy.frame = CGRectMake(154, 61, 70, 29);
        speedBGbox.frame = CGRectMake(234, 50, 74, 14);
        targetSpeed.frame = CGRectMake(228, 61, 48, 29);
        speedLabel.frame = CGRectMake(269, 61, 40, 36);
    

这是一个艰苦的过程,经过多次试验,我在 IB 中可以在几秒钟内完成我在视觉上可以做到的事情。目前,当我在 IB 中的视图之间切换并在横向模式下手动移动元素时,在切换回纵向时,它们位于错误的位置。我已尽可能创造性地使用“弹簧和支柱”,但我的大部分元素都需要在 AutoSizing 范围之外进行精确的手动放置。

我的问题是: IB 中是否有切换模式可以使用可视化布局工具开发视图的两个图形布局,还是数字代码是唯一的方法?

【问题讨论】:

【参考方案1】:

您可以在 nib 文件中创建任意数量的视图。您可以将其中之一称为“纵向视图”(例如,也连接到 File's Owner 的“视图”插座的那个),其中之一称为“横向视图”。将它们都定义为 UIViewController 类中的插座:

@property (nonatomic, retain) IBOutlet UIView *portraitView;
@property (nonatomic, retain) IBOutlet UIView *landscapeView;

根据需要布置 IB 中的字段。那么诀窍是你需要在你的头文件中加倍出口:

@property (nonatomic, retain) IBOutlet UIView *myLabel_portrait;
@property (nonatomic, retain) IBOutlet UIView *myLabel_landscape;

并且在您的代码中,您需要保持两个版本都是最新的。最好是在更新其中一个时同时更新它们。

那么自动旋转的代码真的很简单,只需:

if ( switchingToPortrait)
    self.view = self.portraitView;
else
    self.view = self.landscapeView;

【讨论】:

+1。这样做的缺点是元素不会通过动画重新排列到新位置,您只能为整个视图之间的过渡设置动画。 我会用第三个视图来做到这一点,并在代码中使用纵向视图的框架将所有元素放在“临时”旋转视图上,然后将位置动画到横向视图的位置.它仍然使用我所描述的技术,只是对其进行了扩展。为方便起见,您仍然可以在 IB 中布局横向模式。 感谢 Bogatyr... 澄清:您是说我需要处理的每个标签和按钮都需要 _portrait 和 _landscape 版本?所以基本上在我的代码中,我将同时更新 2 个视图? 进一步...在您对 zoul 的回复中,回复:随机播放动画。如果 shuffle 是必需的,那么第三个视图是否仍然需要对所有位置进行手动编码?我希望 IB/ios 中的一些智能可以在屏幕旋转时“变形”字段位置。 @AcroYogi 1) 是的。然而,我并没有大规模地这样做。您可以编写基于当前方向在横向/纵向之间动态选择的属性设置器函数。您也可以在旋转时将对象设置从纵向复制到横向(反之亦然)。 2)您不需要手动放置任何东西,您可以通过根据帧值放置对象以编程方式进行,然后从当前位置到目标位置执行 UIView 动画,例如【参考方案2】:

我能想到的最好的就是有两个视图,并在didRotateFromInterfaceOrientation:中切换。

【讨论】:

【参考方案3】:

AFAIK 在 Interface Builder 中无法做到这一点。由于视图是从 nib 文件实例化的,因此无论如何您最终都会得到两个实例。

如开发者文档中所述,您可以使用 layoutSubviews,或者像这里一样在视图控制器中使用自定义方法。

【讨论】:

【参考方案4】:

在界面生成器中创建横向和纵向视图。对于每个方向,您的元素就像您想要的那样。当您对外观感到满意时,将坐标复制到您的“positionViews”方法中。

【讨论】:

以上是关于有没有一种方法可以在 Interface Builder 中实际*视觉设计*双视​​图(横向 + 纵向)?的主要内容,如果未能解决你的问题,请参考以下文章

Java-接口(interface)

java里的interface接口类怎么用?

java中的interface

java里的interface接口类怎么用

接口interface

理解Go Interface