当前位置: 首页 > 知识库问答 >
问题:

当用户在swift中将屏幕从纵向转换为横向时,如何使scrollview内部的UIView适应屏幕方向

曾修真
2023-03-14

用户在Swift中将屏幕从纵向转换为横向时,如何使scrollview内部的UIView适应屏幕方向?

var scrollView: UIScrollView = {
    var scroll = UIScrollView()
    scroll.translatesAutoresizingMaskIntoConstraints = false
      
    return scroll
}()

view.addSubview(scrollView)

scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
scrollView.heightAnchor.constraint(equalToConstant: 500).isActive = true

for i in 0..<arr.count {
    var contentView = UIView()
    contentView.frame = CGRect(x: i * Int(view.bounds.size.width) + 10, y: 0, width: Int(view.bounds.size.width) - 20 , height: Int(view.frame.height))

    scrollView.contentSize = CGSize(width: (view.frame.size.width * CGFloat((Double(i)+1))) ,height: scrollView.frame.size.height) 
}

图像

共有2个答案

房唯
2023-03-14

您需要将您的子视图添加到滚动视图并设置它们的约束-使用自动布局。不要使用ContentView.Frame=CGRect(...)和ScrollView.ContentSize=CGSize(...)。

例如,您可以将for-in更改为:

注意:这只是一个示例,请根据您的需要更改您的for-in循环。

for i in 0..<arr.count {

    // we need to distinguish the first and last subviews (because different constraints)
    let topAnchor = i == 0 ? scrollView.topAnchor : scrollView.subviews.last!
    let isLast = i == arr.count - 1

    // here we will use a specific height for all subviews except the last one
    let subviewHeight = 60

    var contentView = UIView()
    contentView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.addSubview(contentView)
    
    if isLast {
        NSLayoutConstraint.activate([
            contentView.topAnchor.constraint(equalTo: topAnchor),
            contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
            contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor)
       ]
    } else {
        NSLayoutConstraint.activate([
            contentView.topAnchor.constraint(equalTo: topAnchor),
            contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
            contentView.heightAnchor.constraint(equalToConstant: subviewHeight),
            contentView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor)
       ]
    }
}
王飞英
2023-03-14

您真的希望使用自动布局,而不是尝试计算帧大小。让它为你做所有的工作。

根据您的代码,看起来您希望每个“ContentView”都是ScrollView框架的宽度减去20(因此每边都有10分的空间)。

通过将contentViews嵌入UISTackView中,可以很容易地实现这一目标。

这里有一个简单的例子:

class ViewController: UIViewController {
    
    var scrollView: UIScrollView = {
        var scroll = UIScrollView()
        scroll.translatesAutoresizingMaskIntoConstraints = false
        
        return scroll
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        
        // use a stack view to hold and arrange the scrollView's subviews
        let stackView = UIStackView()
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.spacing = 20

        // add the stackView to the scrollView
        scrollView.addSubview(stackView)

        // respect safe area
        let safeG = view.safeAreaLayoutGuide
        
        // use scrollView's Content Layout Guide to define scrollable content
        let layoutG = scrollView.contentLayoutGuide

        // use scrollView's Frame Layout Guide to define content height (since you want horizontal scrolling)
        let frameG = scrollView.frameLayoutGuide

        NSLayoutConstraint.activate([
            
            scrollView.topAnchor.constraint(equalTo: safeG.topAnchor, constant: 100),
            
            // you're setting leading and trailing, so no need for centerX
            //scrollView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0),
            
            scrollView.leadingAnchor.constraint(equalTo: safeG.leadingAnchor, constant: 0),
            scrollView.trailingAnchor.constraint(equalTo: safeG.trailingAnchor, constant: 0),
            
            // let's constrain the scrollView bottom to the view (safe area) bottom
            //scrollView.heightAnchor.constraint(equalToConstant: 500),
            scrollView.bottomAnchor.constraint(equalTo: safeG.bottomAnchor, constant: -10.0),
            
            // constrain Top and Bottom of the stackView to scrollView's Content Layout Guide
            stackView.topAnchor.constraint(equalTo: layoutG.topAnchor),
            stackView.bottomAnchor.constraint(equalTo: layoutG.bottomAnchor),
            
            // 10-pts space on leading and trailing
            stackView.leadingAnchor.constraint(equalTo: layoutG.leadingAnchor, constant: 10.0),
            stackView.trailingAnchor.constraint(equalTo: layoutG.trailingAnchor, constant: -10.0),
            
            // constrain stackView's height to scrollView's Frame Layout Guide height
            stackView.heightAnchor.constraint(equalTo: frameG.heightAnchor),
            
        ])
        
        // add some views to the stack view
        let arr: [UIColor] = [
            .red, .green, .blue, .yellow, .purple,
        ]
        
        for i in 0..<arr.count {
            let contentView = UIView()
            contentView.backgroundColor = arr[i]
            stackView.addArrangedSubview(contentView)
            
            // constrain each "contentView" width to scrollView's Frame Layout Guide width minus 20
            contentView.widthAnchor.constraint(equalTo: frameG.widthAnchor, constant: -20).isActive = true
            
            // don't do this
            //contentView.frame = CGRect(x: i * Int(view.bounds.size.width) + 10, y: 0, width: Int(view.bounds.size.width) - 20 , height: Int(view.frame.height))
            
            // don't do this
            //scrollView.contentSize = CGSize(width: (view.frame.size.width * CGFloat((Double(i)+1))) ,height: scrollView.frame.size.height)
            
        }

    }

}

看看这是不是你想要的。

 类似资料:
  • 在Twitter应用程序中,当你点击一条推文时,屏幕会向左滑动,就像页面在滑动一样。我想这是动画部分。我想在我的应用程序中找到它,但在上面找不到任何东西。在我的应用程序中,有许多片段可以多次添加/删除。每个片段上都有按钮,当我点击一个按钮时,新的片段就会出现。我希望他们像推特上的页面一样滑动。我知道ViewPager类,但这是不同的。请帮帮我。谢谢

  • 我正在创建一个全屏灯箱幻灯片/旋转木马,并使用srcset提供最合适的图像。 然而,我不确定如何解决这个问题,因为我的照片是双向的——横向和纵向。 根据图像纵横比、图像大小和屏幕大小,某些图像的最大宽度优先,其他图像的最大高度优先。 在某些情况下,所有图像都在宽度第一(考虑纵向方向)或高度第一(考虑横向方向)时达到最大值。 tl; dr-并不总是宽度或高度被最大化===这很复杂 我怎么能把它写为大

  • 问题内容: 我有两个div彼此相邻浮动。我想要的是在纵向模式下查看时具有100px的宽度,在横向上可以说200 px。这实际上发生在移动设备上。 因此,在横向模式下,div会扩大,在纵向模式下会略微缩小。 有任何想法吗? 问题答案: 好吧,这在CSS2中是不可能的,但是可以使用Javascript做你想做的事情(读出屏幕尺寸等)。 我不确定您正在研究什么技术,但是CSS3正是CSS3 MediaQ

  • 我用Python和Pyplay做了一个简单的游戏。 游戏在两个方向(纵向和横向)上都有效,因为我在打开游戏时使用的方向是相同的。 如果我在游戏运行时旋转设备改变方向,所有东西都会出现在错误的位置。 问题是,我不知道如何检测设备是否已旋转以正确重画屏幕。 那么,我的问题是: 如何检测用户仅使用Python或PyGame代码旋转设备? 重要提示:建议不应与任何特定操作系统相关,因为相同的代码必须在带有

  • 假设用户单击屏幕上的任何位置,我需要将该点,例如(500200)转换为屏幕中心的极点。抽头位置(500,200)从屏幕左上角开始测量。 因此,我必须从一个原点位于屏幕左上角的笛卡尔坐标系转换为另一个原点位于屏幕中间的笛卡尔坐标系(宽度/2,高度/2),然后再从中心原点转换为一个极点。 另一种提问方式是我需要屏幕点与屏幕中心的角度。

  • 问题内容: 我有一个div,当我的页面首次加载时,它离顶部约100像素(该页面包含一些按钮等)。 当用户滚动通过它时,我希望div“关注”该用户,因为它附着在屏幕顶部。当用户返回页面顶部时,我希望它返回到其原始位置。 问题答案: 诀窍是您必须将其设置为position:fixed,但仅在用户滚动经过它之后才能设置。 可以通过将处理程序附加到window.scroll事件来完成此操作 当页面滚动经过