简体   繁体   English

以编程方式滚动 UIScrollView

[英]Programmatically scroll a UIScrollView

I have a UIScrollView which has several views.我有一个UIScrollView有几个视图。 When a user flicks their finger, the view scrolls to the right or left depending on the direction of the finger flick.当用户轻弹手指时,视图会根据手指轻弹的方向向右或向左滚动。 Basically my code works in a way similar to the iPhone photo app.基本上我的代码以类似于 iPhone 照片应用程序的方式工作。 Now, is there a way that I can programmatically do the same thing so that I end up with a slideshow that runs on its own with a click of a button and a configurable pause between each scroll?现在,有没有一种方法可以以编程方式做同样的事情,以便我最终得到一个幻灯片,该幻灯片通过单击按钮和每次滚动之间可配置的暂停而自行运行?

How do you really do slideshows with UIScrollView ?您如何真正使用UIScrollView幻灯片?

You can scroll to some point in a scroll view with one of the following statements in Objective-C您可以使用 Objective-C 中的以下语句之一滚动到滚动视图中的某个点

[scrollView setContentOffset:CGPointMake(x, y) animated:YES];

or Swift或斯威夫特

scrollView.setContentOffset(CGPoint(x: x, y: y), animated: true)

See the guide " Scrolling the Scroll View Content " from Apple as well .另请参阅Apple 的“滚动滚动视图内容”指南

To do slideshows with UIScrollView , you arrange all images in the scroll view, set up a repeated timer, then -setContentOffset:animated: when the timer fires.要使用UIScrollView进行幻灯片放映,您需要在滚动视图中排列所有图像,设置重复计时器,然后在计时器触发时设置-setContentOffset:animated:

But a more efficient approach is to use 2 image views and swap them using transitions or simply switching places when the timer fires.但更有效的方法是使用 2 个图像视图,并在计时器触发时使用过渡或简单地切换位置来交换它们。 See iPhone Image slideshow for details.有关详细信息,请参阅iPhone 图像幻灯片

If you want control over the duration and style of the animation, you can do:如果要控制动画的持续时间和样式,可以执行以下操作:

[UIView animateWithDuration:2.0f delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
    scrollView.contentOffset = CGPointMake(x, y);
} completion:NULL];

Adjust the duration ( 2.0f ) and options ( UIViewAnimationOptionCurveLinear ) to taste!调整持续时间( 2.0f )和选项( UIViewAnimationOptionCurveLinear )来品尝!

另一种方式是

scrollView.contentOffset = CGPointMake(x,y);

Swift 中的动画

scrollView.setContentOffset(CGPointMake(x, y), animated: true)

I'm amazed that this topic is 9 years old and the actual straightforward answer is not here!我很惊讶这个话题已经有 9 年历史了,而真正直接的答案并不在这里!

What you're looking for is scrollRectToVisible(_:animated:) .你要找的是scrollRectToVisible(_:animated:)

Example:例子:

extension SignUpView: UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        scrollView.scrollRectToVisible(textField.frame, animated: true)
    }
}

What it does is exactly what you need, and it's far better than hacky contentOffset它所做的正是你所需要的,而且比 hacky contentOffset好得多

This method scrolls the content view so that the area defined by rect is just visible inside the scroll view.此方法滚动内容视图,以便 rect 定义的区域仅在滚动视图内可见。 If the area is already visible, the method does nothing.如果该区域已经可见,则该方法不执行任何操作。

From: https://developer.apple.com/documentation/uikit/uiscrollview/1619439-scrollrecttovisible来自: https : //developer.apple.com/documentation/uikit/uiscrollview/1619439-scrollrecttovisible

Swift 3斯威夫特 3

let point = CGPoint(x: 0, y: 200) // 200 or any value you like.
scrollView.contentOffset = point
scrollView.setContentOffset(CGPoint(x: y, y: x), animated: true)
[Scrollview setContentOffset:CGPointMake(x, y) animated:YES];
- (void)viewDidLoad
{
    [super viewDidLoad];
    board=[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.height, 80)];
    board.backgroundColor=[UIColor greenColor];
    [self.view addSubview:board];
    // Do any additional setup after loading the view.
}


-(void)viewDidLayoutSubviews
{


    NSString *str=@"ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    index=1;
    for (int i=0; i<20; i++)
    {
        UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(-50, 15, 50, 50)];
        lbl.tag=i+1;
        lbl.text=[NSString stringWithFormat:@"%c",[str characterAtIndex:arc4random()%str.length]];
        lbl.textColor=[UIColor darkGrayColor];
        lbl.textAlignment=NSTextAlignmentCenter;
        lbl.font=[UIFont systemFontOfSize:40];
        lbl.layer.borderWidth=1;
        lbl.layer.borderColor=[UIColor blackColor].CGColor;
        [board addSubview:lbl];
    }

    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(CallAnimation) userInfo:nil repeats:YES];

    NSLog(@"%d",[board subviews].count);
}


-(void)CallAnimation
{

    if (index>20) {
        index=1;
    }
    UIView *aView=[board viewWithTag:index];
    [self doAnimation:aView];
    index++;
    NSLog(@"%d",index);
}

-(void)doAnimation:(UIView*)aView
{
    [UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveLinear  animations:^{
        aView.frame=CGRectMake(self.view.frame.size.height, 15, 50, 50);
    }
                     completion:^(BOOL isDone)
     {
         if (isDone) {
             //do Somthing
                        aView.frame=CGRectMake(-50, 15, 50, 50);
         }
     }];
}

Here is another use case which worked well for me.这是另一个对我来说效果很好的用例。

  1. User tap a button/cell.用户点击按钮/单元格。
  2. Scroll to a position just enough to make a target view visible.滚动到足以使目标视图可见的位置。

Code: Swift 5.3代码: Swift 5.3

// Assuming you have a view named "targeView"
scrollView.scroll(to: CGPoint(x:targeView.frame.minX, y:targeView.frame.minY), animated: true)

As you can guess if you want to scroll to make a bottom part of your target view visible then use maxX and minY.您可以猜到是否要滚动以使目标视图的底部可见,然后使用 maxX 和 minY。

I am showing how to create a simple scroll view with two UIView and add some auto layout constraints so that it will scroll smoothly. 我将展示如何使用两个UIView创建一个简单的滚动视图,并添加一些自动布局约束,以便它可以平滑滚动。

I am supposing that you have an empty view controller in main.storyboard. 我假设你在main.storyboard中有一个空的视图控制器。

1.Add a UIView . 1.添加UIView

let view = UIView()
    view.backgroundColor = UIColor.green
    self.view.addSubview(view)
    view.translatesAutoresizingMaskIntoConstraints = false
    top = view.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0)
    left = view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
    right = view.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0)
    bottom = view.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
    height = view.heightAnchor.constraint(equalToConstant: self.view.frame.height)
    NSLayoutConstraint.activate([top, right, left, height, bottom])

2.Add a ScrollView . 2.添加ScrollView

let scroll = UIScrollView()
    scroll.backgroundColor = UIColor.red
    view.addSubview(scroll)
    scroll.translatesAutoresizingMaskIntoConstraints = false
    top = scroll.topAnchor.constraint(equalTo: view.topAnchor, constant: 10)
    left = scroll.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0)
    right = scroll.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0)
    bottom = scroll.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10)
    NSLayoutConstraint.activate([top, right, left, bottom])

3.Add first UILabel . 3.添加第一个UILabel

 let l2 = UILabel()
        l2.text = "Label1"
        l2.textColor = UIColor.black
        l2.backgroundColor = UIColor.blue
        scroll.addSubview(l2)
        l2.translatesAutoresizingMaskIntoConstraints = false
        top = l2.topAnchor.constraint(equalTo: scroll.topAnchor, constant: 10)
        left = l2.leadingAnchor.constraint(equalTo: scroll.leadingAnchor, constant: 10)
        height = l2.heightAnchor.constraint(equalToConstant: 100)
        right = l2.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10)
        NSLayoutConstraint.activate([top, left, right, height])

4.Add Second UILabel . 4.添加第二个UILabel

let l1 = UILabel()
    l1.text = "Label2"
    l1.textColor = UIColor.black
    l1.backgroundColor = UIColor.blue
    scroll.addSubview(l1)
    l1.translatesAutoresizingMaskIntoConstraints = false
    top = l1.topAnchor.constraint(equalTo: scroll.topAnchor, constant: 1000)
    left = l1.leadingAnchor.constraint(equalTo: scroll.leadingAnchor, constant: 10)
    bottom = l1.bottomAnchor.constraint(equalTo: scroll.bottomAnchor, constant: -10)
    height = l1.heightAnchor.constraint(equalToConstant: 100)
    right = l1.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10)
    NSLayoutConstraint.activate([left, bottom, right, height, top])

LABEL1 在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM