如何使用 swift 创建带有页面控件的滚动视图? [关闭]

Posted

技术标签:

【中文标题】如何使用 swift 创建带有页面控件的滚动视图? [关闭]【英文标题】:How to create a Scroll View with a page control using swift? [closed] 【发布时间】:2015-05-18 10:15:23 【问题描述】:

我正在尝试创建具有视图数量的页面视图控制器。我想要一个使用 UIPageViewController 的简单代码示例。

【问题讨论】:

您可以使用github.com/barankaraoguzzz/FastOnBoarding 轻松工作。请尝试一下。 这不是一个提供现成解决方案或答案的论坛。相反,展示你的努力和尝试了什么,然后在你面临问题的地方寻求解决方案。不鼓励使用整个解决方案。 @Tejas 鼓励在 SO 上回答您自己的问题,以便对未来的读者有所帮助。 @Anish웃 同意。鼓励回答您自己的问题。但是,不鼓励自己寻求端到端的解决方案。 【参考方案1】:
import UIKit

class DummyVC: UIViewController, UIScrollViewDelegate 

    let scrollView = UIScrollView(frame: CGRect(x:0, y:0, width:320,height: 300))
    var colors:[UIColor] = [UIColor.red, UIColor.blue, UIColor.green, UIColor.yellow]
    var frame: CGRect = CGRect(x:0, y:0, width:0, height:0)
    var pageControl : UIPageControl = UIPageControl(frame: CGRect(x:50,y: 300, width:200, height:50))    

    override func viewDidLoad() 
        super.viewDidLoad()

        configurePageControl()

        scrollView.delegate = self
        scrollView.isPagingEnabled = true

        self.view.addSubview(scrollView)
        for index in 0..<4 

            frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
            frame.size = self.scrollView.frame.size

            let subView = UIView(frame: frame)
            subView.backgroundColor = colors[index]
            self.scrollView .addSubview(subView)
        

        self.scrollView.contentSize = CGSize(width:self.scrollView.frame.size.width * 4,height: self.scrollView.frame.size.height)
        pageControl.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)

    

    func configurePageControl() 
        // The total number of pages that are available is based on how many available colors we have.
        self.pageControl.numberOfPages = colors.count
        self.pageControl.currentPage = 0
        self.pageControl.tintColor = UIColor.red
        self.pageControl.pageIndicatorTintColor = UIColor.black
        self.pageControl.currentPageIndicatorTintColor = UIColor.green
        self.view.addSubview(pageControl)

    

    // MARK : TO CHANGE WHILE CLICKING ON PAGE CONTROL
    func changePage(sender: AnyObject) -> () 
        let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
        scrollView.setContentOffset(CGPoint(x:x, y:0), animated: true)
    

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) 

        let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
        pageControl.currentPage = Int(pageNumber)
    


【讨论】:

很棒的入门代码,谢谢! @anishparajuli:请看一下:href="***.com/questions/36174529/… 我已按照本教程 (raywenderlich.com/76436/…) 进行操作,该教程与您的代码非常相似,但我无法使其工作 我在 UIView 类中使用此方法。对此var frame: CGRect = CGRectMake(0, 0, 0, 0) 有很大的问题。这个名字frame不应该使用,重命名为其他。 frameself.frame 产生冲突 您的代码帮助很大。我试着采取下一步。 ***.com/questions/40996685/…【参考方案2】:

对于懒惰的编码器,这是基于That lazy ios Guy 웃 的答案的 Swift 3 实现

import UIKit

class ViewController: UIViewController,UIScrollViewDelegate 

    let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 320, height: 300))
    var colors:[UIColor] = [UIColor.red, UIColor.blue, UIColor.green, UIColor.yellow]
    var frame: CGRect = CGRect(x: 0, y: 0, width: 0, height: 0)
    var pageControl : UIPageControl = UIPageControl(frame:CGRect(x: 50, y: 300, width: 200, height: 50))


    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        configurePageControl()

        scrollView.delegate = self
        self.view.addSubview(scrollView)
        for index in 0..<4 

            frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
            frame.size = self.scrollView.frame.size

            let subView = UIView(frame: frame)
            subView.backgroundColor = colors[index]
            self.scrollView .addSubview(subView)
        
        self.scrollView.isPagingEnabled = true
        self.scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width * 4, height: self.scrollView.frame.size.height)
        pageControl.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)

    

    func configurePageControl() 
        // The total number of pages that are available is based on how many available colors we have.
        self.pageControl.numberOfPages = colors.count
        self.pageControl.currentPage = 0
        self.pageControl.tintColor = UIColor.red
        self.pageControl.pageIndicatorTintColor = UIColor.black
        self.pageControl.currentPageIndicatorTintColor = UIColor.green
        self.view.addSubview(pageControl)

    

    // MARK : TO CHANGE WHILE CLICKING ON PAGE CONTROL
    func changePage(sender: AnyObject) -> () 
        let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
        scrollView.setContentOffset(CGPoint(x: x,y :0), animated: true)
    

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) 

        let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
        pageControl.currentPage = Int(pageNumber)
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    


【讨论】:

很好的答案!对于 Swift 3,我们应该将 Selector(("changePage:")) 更改为 #selector(self.changePage(sender:)) self.scrollView.isPagingEnabled = true 应该在 外部 for 循环 此代码无法正常工作,因为如果您使用 AutoLayout,则滚动视图框架还不正确。确保添加 scrollView.setNeedsLayout() 或 scrollView.layoutIfNeeded()【参考方案3】:

Swift 3 - 水平图像滚动

import UIKit

class pageenabled: UIViewController,UIScrollViewDelegate 

    let imagelist = ["img1.jpg", "photo1.jpg", "photo3.jpg", "photo4.jpg", "photo5.jpg"]
    var scrollView = UIScrollView()

    var pageControl : UIPageControl = UIPageControl(frame:CGRect(x: 50, y: 300, width: 200, height: 50))

    var yPosition:CGFloat = 0
    var scrollViewContentSize:CGFloat=0;

    override func viewDidLoad() 
        super.viewDidLoad()

        scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 300))

        configurePageControl()

        scrollView.delegate = self
        self.view.addSubview(scrollView)
        for  i in stride(from: 0, to: imagelist.count, by: 1) 
            var frame = CGRect.zero
            frame.origin.x = self.scrollView.frame.size.width * CGFloat(i)
            frame.origin.y = 0
            frame.size = self.scrollView.frame.size
            self.scrollView.isPagingEnabled = true

            let myImage:UIImage = UIImage(named: imagelist[i])!
            let myImageView:UIImageView = UIImageView()
            myImageView.image = myImage
            myImageView.contentMode = UIViewContentMode.scaleAspectFit
            myImageView.frame = frame

            scrollView.addSubview(myImageView)
        

        self.scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width * CGFloat(imagelist.count), height: self.scrollView.frame.size.height)
        pageControl.addTarget(self, action: Selector(("changePage:")), for: UIControlEvents.valueChanged)
        // Do any additional setup after loading the view.
    
    func configurePageControl() 
        // The total number of pages that are available is based on how many available colors we have.
        self.pageControl.numberOfPages = imagelist.count
        self.pageControl.currentPage = 0
        self.pageControl.tintColor = UIColor.red
        self.pageControl.pageIndicatorTintColor = UIColor.black
        self.pageControl.currentPageIndicatorTintColor = UIColor.green
        self.view.addSubview(pageControl)

    

    // MARK : TO CHANGE WHILE CLICKING ON PAGE CONTROL
    func changePage(sender: AnyObject) -> () 
        let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
        scrollView.setContentOffset(CGPoint(x: x,y :0), animated: true)
    

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) 

        let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
        pageControl.currentPage = Int(pageNumber)
    
    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

【讨论】:

【参考方案4】:
       @IBOutlet weak var scrollView: UIScrollView! 
@IBOutlet weak var imageViewBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var imageViewLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var imageViewTopConstraint: NSLayoutConstraint!
@IBOutlet weak var imageViewTrailingConstraint: NSLayoutConstraint!

extension ZoomedPhotoViewController: UIScrollViewDelegate 
  func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? 
    return imageView
  

private func updateMinZoomScaleForSize(size: CGSize) 
  let widthScale = size.width / imageView.bounds.width
  let heightScale = size.height / imageView.bounds.height
  let minScale = min(widthScale, heightScale)  

  scrollView.minimumZoomScale = minScale 

  scrollView.zoomScale = minScale



override func viewDidLayoutSubviews() 
  super.viewDidLayoutSubviews()

  updateMinZoomScaleForSize(view.bounds.size)


private func updateConstraintsForSize(size: CGSize)    

  let yOffset = max(0, (size.height - imageView.frame.height) / 2) 
  imageViewTopConstraint.constant = yOffset
  imageViewBottomConstraint.constant = yOffset

  let xOffset = max(0, (size.width - imageView.frame.width) / 2)
  imageViewLeadingConstraint.constant = xOffset
  imageViewTrailingConstraint.constant = xOffset

  view.layoutIfNeeded()

func scrollViewDidZoom(scrollView: UIScrollView) 
  updateConstraintsForSize(view.bounds.size) 


import UIKit

public class PhotoCommentViewController: UIViewController   
  @IBOutlet weak var imageView: UIImageView!
  @IBOutlet weak var scrollView: UIScrollView!
  @IBOutlet weak var nameTextField: UITextField!
  public var photoName: String!

  override public func viewDidLoad() 
    super.viewDidLoad()
    if let photoName = photoName 
      self.imageView.image = UIImage(named: photoName)
    
  

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
  if let cell = sender as? UICollectionViewCell,
      indexPath = collectionView?.indexPathForCell(cell),
      photoCommentViewController = segue.destinationViewController as? PhotoCommentViewController 
    photoCommentViewController.photoName = "photo\(indexPath.row + 1)"
  

NSNotificationCenter.defaultCenter().addObserver(
  self,
  selector: #selector(PhotoCommentViewController.keyboardWillShow(_:)),
  name: UIKeyboardWillShowNotification,
  object: nil
)
NSNotificationCenter.defaultCenter().addObserver(
  self,
  selector: #selector(PhotoCommentViewController.keyboardWillHide(_:)),
  name: UIKeyboardWillHideNotification,
  object: nil
) 
deinit 
  NSNotificationCenter.defaultCenter().removeObserver(self)


func adjustInsetForKeyboardShow(show: Bool, notification: NSNotification) 
  guard let value = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue else  return 
  let keyboardFrame = value.CGRectValue()
  let adjustmentHeight = (CGRectGetHeight(keyboardFrame) + 20) * (show ? 1 : -1)
  scrollView.contentInset.bottom += adjustmentHeight
  scrollView.scrollIndicatorInsets.bottom += adjustmentHeight


func keyboardWillShow(notification: NSNotification) 
  adjustInsetForKeyboardShow(true, notification: notification)


func keyboardWillHide(notification: NSNotification) 
  adjustInsetForKeyboardShow(false, notification: notification)
  
@IBAction func hideKeyboard(sender: AnyObject) 
  nameTextField.endEditing(true)

public var photoIndex: Int!



import UIKit

class ManagePageViewController: UIPageViewController 
  var photos = ["photo1", "photo2", "photo3", "photo4", "photo5"]
  var currentIndex: Int!

  override func viewDidLoad() 
    super.viewDidLoad()

    dataSource = self

    // 1
    if let viewController = viewPhotoCommentController(currentIndex ?? 0) 
      let viewControllers = [viewController]
      // 2
      setViewControllers(
        viewControllers,
        direction: .Forward,
        animated: false,
        completion: nil
      )
    
  

  func viewPhotoCommentController(index: Int) -> PhotoCommentViewController? 
    if let storyboard = storyboard,
        page = storyboard.instantiateViewControllerWithIdentifier("PhotoCommentViewController") 
        as? PhotoCommentViewController 
      page.photoName = photos[index]
      page.photoIndex = index
      return page
    
    return nil
  

【讨论】:

您好,欢迎您!一些解释会显着提高您的回答质量【参考方案5】:

Swift 3.0 中 通过故事板为滚动视图和页面控制器创建 ioutlets。

@IBOutlet weak var imgScrollView: UIScrollView!
@IBOutlet weak var imgPageController: UIPageControl!
var sliderImagesArray = NSMutableArray()

在 viewdidload 方法中写下这段代码

sliderImagesArray = ["https://images.unsplash.com/photo-1432679963831-2dab49187847?w=1080","https://images.unsplash.com/photo-1447746249824-4be4e1b76d66?w=1080", "https://images.unsplash.com/photo-1463595373836-6e0b0a8ee322?w=1080"]
    imgScrollView.delegate = self
for i in 0..<sliderImagesArray.count 
        var imageView : UIImageView
        let xOrigin = self.imgScrollView.frame.size.width * CGFloat(i)
        imageView = UIImageView(frame: CGRect(x: xOrigin, y: 0, width: self.imgScrollView.frame.size.width, height: self.imgScrollView.frame.size.height))
        imageView.isUserInteractionEnabled = true
        let urlStr = sliderImagesArray.object(at: i)
        print(imgScrollView,imageView, urlStr)
        imageView.sd_setImage(with: URL(string: urlStr as! String), placeholderImage: UIImage(named: "placeholder.png"))
        imageView .contentMode = UIViewContentMode.scaleToFill
        self.imgScrollView.addSubview(imageView)
    
    self.imgScrollView.isPagingEnabled = true
    self.imgScrollView.bounces = false
    self.imgScrollView.showsVerticalScrollIndicator = false
    self.imgScrollView.showsHorizontalScrollIndicator = false
    self.imgScrollView.contentSize = CGSize(width: 
    self.imgScrollView.frame.size.width * CGFloat(sliderImagesArray.count), height: self.imgScrollView.frame.size.height)
    imgPageController.addTarget(self, action: #selector(self.changePage(sender:)), for: UIControlEvents.valueChanged)

    self.imgPageController.numberOfPages = sliderImagesArray.count
    self.imgPageController.currentPage = 0
    self.imgPageController.tintColor = UIColor.red
    self.imgPageController.pageIndicatorTintColor = UIColor.black
    self.imgPageController.currentPageIndicatorTintColor = UIColor.blue

之后实现滚动视图委托方法

func changePage(sender: AnyObject) -> () 
    let x = CGFloat(imgPageController.currentPage) * imgScrollView.frame.size.width
    imgScrollView.setContentOffset(CGPoint(x: x,y :0), animated: true)

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) 

    let pageNumber = round(imgScrollView.contentOffset.x / imgScrollView.frame.size.width)
    imgPageController.currentPage = Int(pageNumber)

【讨论】:

以上是关于如何使用 swift 创建带有页面控件的滚动视图? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

swift中标签的页面控制

使用滚动视图和页面控制?

如何使页面控件在每个视图中显示文本

如何在 Swift 中构建这个布局

如何在 Swift 中使用带有滚动视图的自动布局?

我的带有自动布局约束的 Swift 4 UIScrollView 没有滚动