UIScrollview 宽度不能与 iPhone 大小相等

Posted

技术标签:

【中文标题】UIScrollview 宽度不能与 iPhone 大小相等【英文标题】:UIScrollview width does not Scale equally to iPhone size 【发布时间】:2016-12-26 04:52:26 【问题描述】:

我正在尝试创建一个滚动对象数组的全屏滚动视图。在故事板中,我只有一个滚动视图锚定在超级视图的边缘,因此它是全屏的。为数组中的每个对象创建一个带有文本字段的新视图(参见代码)。

滚动视图在 6s Size 上完美运行,但在 SE 模拟器上运行时,我得到不同的结果。滚动视图完全搞砸了(见下文

以下是我的滚动视图设置:

下面是我的代码。它的目标是为每个对象创建一个视图并显示其文本。

 class ViewController: UIViewController 

//Create your connection from your storyboard
@IBOutlet weak var scrollView: UIScrollView!

// This is an array of views that will be appended to the scroll view later.
// These can be images or whatever want
var mainViews = [UIView]()

// This is an array of objects that are modeled off the SampleObjcet class we created earlier.
// They all contain diffrent strings to display. We will add the text as they are created
var arrayOfSampleObjects = [
    SampleObject(sampleText: "Page 1"),SampleObject(sampleText: "Page 2"),
    SampleObject(sampleText: "Page 3"),SampleObject(sampleText: "Page 4"),
]

override func viewDidLoad() 
    super.viewDidLoad()

    // contentWidth is a varible that controlls the width of the scroll view
    // This variabel grows each time a view is added
    var contentWidth: CGFloat = 0.0

    // scrollviewWidth & scrollviewHeight hold the sizes so we can use them to 
    // calculate the diffrent views later
    let scrollviewWidth = scrollView.frame.size.width
    let scrollviewHeight = scrollView.frame.size.height

    // This is where the magic happens. 
    // This for loop goes through the array of objects and create views for each object.
    for object in 0..<arrayOfSampleObjects.count 

        // textToShowInformation is a label made to show the text from the diffrent objects.
        // Sets up text properties
        let textToShowInformation = UILabel()
        textToShowInformation.text = arrayOfSampleObjects[object].sampleText // Goes through the arrayOfSampleObjects infromation
        textToShowInformation.translatesAutoresizingMaskIntoConstraints = false
        textToShowInformation.textAlignment = .center

        // viewToShowInformation is the view that wil be created for each object
        // for example, if there are 50 objects, there will be 50 views.
        let viewToShowInformation = UIView()

        // This adds the diffrent views to the mainViews array to be displayed
        mainViews.append(viewToShowInformation)

        // ERROR
        // come back to this.... the calculations only work for 6s -_-
        var newX: CGFloat = 0.0

        //object in an index so if its object 4,
        //it will be 4x' s as wide...i think...
        newX = scrollviewWidth * CGFloat(object)


        contentWidth += newX - scrollviewWidth
        scrollView.addSubview(viewToShowInformation)
        viewToShowInformation.addSubview(textToShowInformation)
        viewToShowInformation.frame = CGRect(x: newX, y:0, width: scrollviewWidth, height: scrollviewHeight)

        // Constraints for the text fields. Center Everything...
        textToShowInformation.centerXAnchor.constraint(equalTo: viewToShowInformation.centerXAnchor).isActive = true
        textToShowInformation.centerYAnchor.constraint(equalTo: viewToShowInformation.centerYAnchor).isActive = true
    

    // Sets up the scroll view properties
    scrollView.bounces = true // allows views to bounce past the scrollview width. change to personal preferance
    // Below controlls the width size of the scrollview,I think the problem could lie here too
    scrollView.contentSize = CGSize(width: scrollView.frame.size.width * CGFloat(arrayOfSampleObjects.count), height:scrollviewHeight)
    scrollView.clipsToBounds = false // important


一切都适用于 6-6s,但是当它在 SE 上运行时,文本没有居中。 文本锚定在添加的视图的中间

如果你在这里看不清楚,这里是 repo 的链接,你可以测试一下:object_controlled_scrollview

【问题讨论】:

【参考方案1】:

您正在viewDidLoad-中执行以下代码块-

let scrollviewWidth = scrollView.frame.size.width
let scrollviewHeight = scrollView.frame.size.height

您的自动布局尚未实现。所以最初你的 scrollViewWidthscrollViewHeight 被设置为你在故事板中设计项目的任何大小。

尝试将设置UIScrollView 的整个代码块移动到viewDidLayoutSubviewsviewDidAppear

您可以尝试在super.viewDidLoad() 之后强制调用view.layoutIfNeeded()

【讨论】:

其他的方法我没试过,但是放到viewDidAppear里面就解决了!谢谢! 确保您只在viewDidAppear 中执行一次,因为该函数会被多次调用! 调用view.layoutIfNeeded() 有效,我将使用它!谢谢!【参考方案2】:

尝试添加到下面的代码行:

scrollView.setNeedsLayout()
scrollView.layoutIfNeeded()

【讨论】:

感谢您的回答,但是这个回答不起作用。

以上是关于UIScrollview 宽度不能与 iPhone 大小相等的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 跨设备 UI 兼容性

Swift - 以编程方式将 UIScrollView 宽度设置为 100%

iphone uiscrollview - 自定义分页距离

iOS UIScrollView 的宽度与约束中设置的宽度不同

UIScrollView scrollToTop 没有被 iPhone 调用

Swift UIScrollView 在没有 pagingEnabled 的情况下捕捉到子视图宽度