不同屏幕尺寸的 iOS 缩放约束

Posted

技术标签:

【中文标题】不同屏幕尺寸的 iOS 缩放约束【英文标题】:iOS Scaling Constraints for Different Screen Sizes 【发布时间】:2015-06-02 18:07:50 【问题描述】:

这是我的第一个 ios 应用程序,我正在使用 Swift。我正在关注 CodeWithChris.com 上的教程。

用户将点击一系列图标来确定他们拥有的设备型号。到目前为止,我已经使用了一些约束来将图标正确放置在 iPhone 6 显示屏上。当使用 iPhone 5S/5c/5 或 4S/4 显示尺寸时,图标和文本仍以 iPhone 6 的完整尺寸呈现,并且它们会离开屏幕。

这是我构建布局的过程:

    抓取 JSON 并将其解析为 NSArray。返回 ["iPhone"、"android"、"Windows"、"iPad"] 为 NSArray 中的每个项目创建 UIView 对象。将 Name 变量设置为关联的名称。 使用 addSubview() 放置每个 UIView 对 UIView 应用高度、宽度和下边距约束 根据 UIView 在行中的位置设置 UIView 位置约束 为每个 UIView 添加图标(UIImageViews) 根据设备类型设置高度和宽度限制 添加文字标签

我正在使用一堆约束来放置 UIView 和 UIImageView。如何根据设备的屏幕尺寸使这些约束动态化?

iPhone 6 的 contentView 为蓝色,UIViews 为红色

iPhone 6

iPhone 5/5S/5c

iPhone 4S/4

这里是我添加设备 UIView 并应用约束的地方:

    // Loop through the array of DeviceTypes to add each to the UIView
    for index in 0...deviceTypes.count-1 

        // Grab the current device
        var thisDevice:DeviceType = deviceTypes[index]


        // Add to the view!
        contentView.addSubview(thisDevice)
        thisDevice.setTranslatesAutoresizingMaskIntoConstraints(false)


        // How tall is the Device UIView
        var heightConstraint:NSLayoutConstraint = NSLayoutConstraint(item: thisDevice, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 200)

        // How wide is the device UIView
        var widthConstraint:NSLayoutConstraint = NSLayoutConstraint(item: thisDevice, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 130)

        // How far is the bottom of the UIView from the top of the contentView
        var bottomMarginConstraint:NSLayoutConstraint = NSLayoutConstraint(item: thisDevice, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 100)


        // Add thisDevice's UIView constraints
        thisDevice.addConstraints([heightConstraint, widthConstraint])
        contentView.addConstraint(bottomMarginConstraint)
        thisDevice.backgroundColor = UIColor.redColor()


        // set UIView position constraints based on place in row
        if (index > 0) 
            // device is second or further in row
            var deviceOnTheLeft = deviceTypes[index-1]

            var leftMarginConstraint:NSLayoutConstraint = NSLayoutConstraint(item: thisDevice, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: deviceOnTheLeft, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 10)

            contentView.addConstraint(leftMarginConstraint)
        
        else 
            // device is first in row
            var leftMarginConstraint:NSLayoutConstraint = NSLayoutConstraint(item: thisDevice, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 0)

            // Add constraint
            contentView.addConstraint(leftMarginConstraint)
        

以下是我对图标图像应用的约束:

func addDeviceImages() 

    // Set right image based on deviceType name
    self.frontImageView.image = UIImage(named: self.Name!)

    // Set translates autoresizing mask to fault
    self.frontImageView.setTranslatesAutoresizingMaskIntoConstraints(false)

    // Add the imageview to the view
    self.addSubview(self.frontImageView)

    if (self.Name == "Windows") 
        self.addImageSizeConstraints(90, height: 160)
    

    else if (self.Name == "iPad")
        self.addImageSizeConstraints(120, height: 180)
    

    else if (self.Name == "iPhone")
        self.addImageSizeConstraints(85, height: 175)
    

    else if (self.Name == "Android")
        self.addImageSizeConstraints(95, height: 185)
    



func addImageSizeConstraints(width: CGFloat, height: CGFloat) 

    // Set the size constraints for the imageview based on the values passed in
    var heightConstraint:NSLayoutConstraint = NSLayoutConstraint(item: self.frontImageView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: height)

    var widthConstraint:NSLayoutConstraint = NSLayoutConstraint(item: self.frontImageView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: width)

    self.frontImageView.addConstraints([heightConstraint, widthConstraint])


    // Set the position of the imageview in the UIView
    var verticalConstraint:NSLayoutConstraint = NSLayoutConstraint( item: self.frontImageView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: -25)

    var horizontalConstraint:NSLayoutConstraint = NSLayoutConstraint( item: self.frontImageView, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 5)

    self.addConstraints([horizontalConstraint,verticalConstraint])

【问题讨论】:

为什么不使用集合视图为您完成所有这些工作?它将让您设计流程布局并让您调整每个单元格的大小。 developer.apple.com/library/ios/documentation/WindowsViews/… 谢谢 Rory,我会多读一些关于集合视图和流布局的文章。 【参考方案1】:

您使用了错误类型的约束。您的宽度限制是绝对的 - 您正在设置一个固定的constant。相反,将constant 设为0,宽度取决于高度,使用multiplier 的值正确固定纵横比。这样,随着高度的变化,宽度也会随之变化。对图像之间的分离做同样的事情 - 使分离取决于超级视图的宽度,作为乘数。

【讨论】:

谢谢马特。好建议。你能举个例子说明如何访问超级视图宽度并将其设置为乘数吗? 您不“访问”它,您只是在创建宽度约束时将其用作其他值。例如,请参阅我的答案:***.com/questions/26373598/…

以上是关于不同屏幕尺寸的 iOS 缩放约束的主要内容,如果未能解决你的问题,请参考以下文章

当我们使用不同尺寸和类型的屏幕时,如何在 iOS 中设置 UI 控件的宽度和高度约束?

ConstraintLayout 不缩放以适应各种屏幕尺寸

iOS,布局位置取决于屏幕尺寸问题

xcode ios - 如何使图像适合不同的屏幕尺寸

为谷歌 DFP 广告缩放到不同的安卓屏幕尺寸 - Phonegap

如果宽度大于屏幕尺寸,iOS/Android 上的高度也会改变(约束问题)