Swift UIScrollView -仅垂直滚动的正确实现

6ioyuze2  于 2023-03-07  发布在  Swift
关注(0)|答案(8)|浏览(228)

事先,我道歉,因为我会说,我是一个初学者与iOS编程。
我想使用UIScrollView,因为要显示的内容超过了屏幕的高度。因此,我只想垂直滚动,而不是水平滚动。
我正在使用脚本来绘制AutoLayout视图。
下面是我的UIViewControllerUIScrollView的屏幕截图:

然后将Label更改为这样的大文本

override func viewDidLoad() {
    super.viewDidLoad()

    self.label1Label.text = "Seize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel KafandoSeize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel Kafando"
    self.label1Label.numberOfLines = 0
    self.label1Label.sizeToFit()

我的问题是,如果我不手动设置contentView的宽度(在UIScrollView中),滚动是水平的,而不是垂直的。(看下面的截图):

我试着设置contentSize,因为我已经看到许多谷歌帖子,但没有成功:

self.scrollView.contentSize = CGSizeMake(400.0, 600.0)

如果我手动设置contentview的宽度(i.e : 320pts),滚动将是垂直的(良好),但根据iphone的大小,它不会覆盖整个屏幕宽度,如下图所示:

问题是:使用UIScrollView来使contentView遵守自动布局约束(full screen : 0top - 0bottom - 0left - 0right)并且滚动仅为垂直的正确实现是什么?
非常感谢你的帮助!

hsvhsicv

hsvhsicv1#

MikeWoelmer在AtomicObject博客上展示了如何使用接口构建器正确地完成这一操作。
http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/
我在github上也只有自己的代码(没有故事板实现)。
https://github.com/nadthevlad/AutolayotScrollview
您不希望设置内容或视图的高度或宽度,而是希望使用自动布局固定点和约束来设置滚动视图的行为。
1.创建UIScrollView * 滚动视图。
1.您希望创建一个UIView *contentView,并将其余视图元素放入其中。

[self.view addSubview:scrollView];
[scrollView addSubview:contentView];
[contentView addSubview:_label1];
[contentView addSubview:_label2];
[contentView addSubview:_label3];
[contentView addSubview:_label4];
[contentView addSubview:_label5];
[contentView addSubview:_label6];

1.将scrollView的4个边缘固定到self.view的4个边缘
1.将contentView的上边缘和下边缘固定到scrollView的顶部和底部。
1.这是一个棘手的部分。要设置水平大小,您需要将contentView的前(右)边和后(左)边固定到self.view而不是scrollView的前(左)边和后(左)边。即使contentView是scrollView的子视图,其水平约束也会超出scrollView并连接到self.view。
1.像往常一样将任何其他视图元素固定到contentView。

mctunoxg

mctunoxg2#

允许UIScrollView仅在一个方向上滚动的技巧是使受限维度的UIScrollView的内容大小与同一维度中UIScrollView的框架大小相同。因此,在本例中,scrollview.contentSize.width应等于scrollview.frame.size.width
记住这一点,尝试以下方法:
1.确保按照this answer中所述的相同方式设置约束
1.将以下代码添加到视图控制器:

override func viewWillLayoutSubviews()
{
    super.viewWillLayoutSubviews();
    self.scrollView.contentSize.height = 3000; // Or whatever you want it to be.
}

就个人而言,我真的不是一个自动布局的爱好者。如果你有兴趣在没有自动布局的情况下尝试这个功能--即只使用代码而不是约束--你可以关闭视图控制器视图的自动布局,并将你的viewWillLayoutSubviews方法修改为如下所示:

override func viewWillLayoutSubviews()
{
    super.viewWillLayoutSubviews();

    self.scrollView.frame = self.view.bounds; // Instead of using auto layout
    self.scrollView.contentSize.height = 3000; // Or whatever you want it to be.
}
6xfqseft

6xfqseft3#

这就是我总是做的垂直滚动从故事板与约束:
1-拖动视图控制器
2-将控制器主视图中的一个滚动视图(带有约束L = 0、T = 0、T = 0和B = 0)拖动到其超级视图(控制器主视图)。
3-将一个UIView拖动到滚动视图中,作为其内容视图,并对其超级视图(滚动视图)进行约束L-0、T = 0、T = 0、B = 0

  • 好了,现在是时候设置滚动视图的内容大小了,它可以控制水平和垂直滚动,如下所示。

4-为了停止水平滚动,使内容视图宽度与滚动视图宽度相等。
5-使内容视图的高度等于控制器视图的高度,这是临时的*直到我们用可滚动的内容填充它 *。
6-在内容视图中添加控件直到完成.
7-最重要的是删除你在第5点中对内容视图高度的限制,而不是从内容视图底部的控件中进行限制,使其底部对齐。这有助于使内容视图高度从顶部的第一个控件开始,向下直到最后一个控件(这完全取决于这一步)。
8-只要运行和结果应该是预期的,否则请让我知道。
希望这有帮助!

s1ag04yj

s1ag04yj4#

您可以正常定义ScrollView并正常约束ScrollView的属性

let scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.backgroundColor = .white
    self.view.addSubview(scrollView)

    scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0.0).isActive = true
    scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0.0).isActive = true
    scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0.0).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0).isActive = true

但诀窍在于如何定义可能比屏幕宽的Label(或其他视图)。

myLabel.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -10.0).isActive = true

您应该使用

myLabel.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10.0).isActive = true

这第二行将阻止该视图引起水平滚动。对所有子视图都这样做,您将不会水平滚动。(它仍将按计划垂直滚动。)
另外,不要忘记在最后一个子视图上设置底部约束,以确保UIScrollview垂直滚动。

labelX.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -10.0).isActive = true
vu8f3i0k

vu8f3i0k5#

多亏了@NadtheVlad,我终于明白了。一些进一步的摸索告诉我,contentView只需要固定到scrollView的顶部、底部和宽度。不需要引用self. view。
对于EasyPeasy,这很简单:

scrollView <- Edges()
contentView <- [Top(), Bottom(), Width().like(scrollView)]
5anewei6

5anewei66#

我迟到了..如果你给予标签的宽度约束等于视图,那么你可以实现同样的事情

aboutCaption.widthAnchor.constraint(equalTo: self.view.widthAnchor , multiplier: 0.9).isActive = true

这是我的示例代码

class AboutVC: UIViewController{

let scrollView = UIScrollView()

lazy var aboutLbl : UILabel = {
    let lbl = UILabel()
    lbl.text = "About"
    lbl.font = .boldSystemFont(ofSize: 19)
    return lbl
}()

lazy var aboutCaption : UILabel = {
    let lbl = UILabel()
    lbl.text = "Hi. My name is Uzumaki Naruto. I am a professional MMA Coach with 15+ years of experience. I specialize in ninjutsu, shadow clones and various other techniques. I am in the TOP50 coaches in the Sports category. Been with GIGIMOT for 5 years already. Not a single bad review. "
    lbl.numberOfLines = 0
    lbl.font  = UIFont(name: "Helvetica Neue Thin", size: 16)!
    lbl.textColor = .systemGray2
    return lbl
}()

override func viewDidLoad() {
    super.viewDidLoad()
    configureUI()
    //        tableView.dataSource = self
    //        tableView.delegate = self
}

func configureUI() {
    self.view.backgroundColor = UIColor.white
    
    //Add and setup scroll view
    self.view.addSubview(self.scrollView)
    scrollView.backgroundColor = .white
    self.scrollView.translatesAutoresizingMaskIntoConstraints = false;
    self.scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true;
    self.scrollView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true;
    self.scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true;
    self.scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true;
    
    scrollView.addSubview(aboutLbl)
    
    aboutLbl.anchor(top: scrollView.topAnchor, left: scrollView.leftAnchor , paddingTop: 10 , paddingLeft: 10)
    
    
    scrollView.addSubview(aboutCaption)
    aboutCaption.anchor(top: aboutLbl.bottomAnchor, left: scrollView.leftAnchor, bottom: scrollView.bottomAnchor , right: scrollView.rightAnchor, paddingTop: 10, paddingLeft: 10, paddingBottom: 10, paddingRight: 0)
    aboutCaption.widthAnchor.constraint(equalTo: self.view.widthAnchor , multiplier: 0.9).isActive = true
    
}}
sg24os4d

sg24os4d7#

2023年的确切答案:

垂直示例:

var scroll: UIScrollView
var tall: UIView // some tall view, imagine a few screen heights.

1.固定scroll的大小,并对其超级视图进行上/右/下/左约束。
1.使tall成为scroll的子视图。
1.* * 信不信由你**,对于tall,设置***底部、顶部和宽度***等于其超级视图(即滚动)。
这就是它的全部。
显然,不要忘记固有地设置tall的高度。(例如,如果它是10个标签,显然要将它们连接起来,以便tall的高度由这些标签设置,或者您在tall中所做的任何事情。当然,不要忘记translatesAutoresizingMaskIntoConstraints = false

mwngjboj

mwngjboj8#

我只在水平/垂直滚动视图中使用这个实现,尽管它是在Objective-C中,如果有什么不清楚的地方,我会尝试解释它的逻辑。

//Getting iDevice's screen width
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;

//Setting the right content size - only height is being calculated depenging on content.
CGSize contentSize = CGSizeMake(screenWidth, HEIGHT_OF_YOUR_CONTENT);
self.scrollView.contentSize = contentSize;

现在,scrollview的contentSize属性的宽度被附加到设备屏幕的实际宽度,因此scrollview将仅在垂直方向上滚动。

相关问题