自動で横スクロールするページに制約をつける

##参考記事に制約をつける
https://www.hfoasi8fje3.work/entry/2019/02/20/233607

# UIScrollViewにコードで制約をつける
```swift
import UIKit

final class ViewController: UIViewController {
    
    struct Photo {
        var imageName: String
    }
    //型のネスト  [ViewController.Photo]
    var photoList = [
        Photo(imageName: "gear"),
        Photo(imageName: "magnifyingglass"),
        Photo(imageName: "clock")
    ]
    
    private lazy var scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.showsVerticalScrollIndicator = false
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()
    
    
    private var pageControl: UIPageControl = {
        let pageControl = UIPageControl()
        pageControl.numberOfPages = 3
        pageControl.pageIndicatorTintColor = UIColor.lightGray
        pageControl.backgroundColor = .green
        pageControl.currentPageIndicatorTintColor = UIColor.black
        return pageControl
    }()
    
    private lazy var button: UIButton = {
        let button = UIButton()
        button.backgroundColor = .orange
        button.setTitle("戻る", for: .normal)
        button.tintColor = .white
        button.addTarget(self, action: #selector(didTapDone), for: .touchUpInside)
        return button
    }()
    
    private var offsetX: CGFloat = 0
    private var timer: Timer!
    
    //MARK: - ライフサイクル等
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let frameGuide = scrollView.frameLayoutGuide
        
        scrollView.delegate = self
        scrollView.backgroundColor = .green
        
        view.addSubview(scrollView)
        
        view.addSubview(pageControl)
        
        frameGuide.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        frameGuide.topAnchor.constraint(equalTo:  pageControl.bottomAnchor, constant: -5).isActive = true
        frameGuide.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        frameGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor,constant: -view.bounds.height / 4).isActive = true
    
        setUpImageView()
        
        pageControl.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: view.safeAreaLayoutGuide.leadingAnchor, bottom: nil, trailing: view.safeAreaLayoutGuide.trailingAnchor, padding: .init(top: 2, left: 0, bottom: 0, right: 0),size: .init(width: view.frame.size.width, height: 20))
        pageControl.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        view.addSubview(button)
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.anchor(top: scrollView.bottomAnchor, leading: nil, bottom: nil, trailing: nil, padding: .init(top: 5, left:0 , bottom: 0, right: 0),size: .init(width:view.frame.size.width / 2, height: 50))
        // タイマーを作成
        self.timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.scrollPage), userInfo: nil, repeats: true)
    }
    
    // viewWillDisappearされたらタイマーが破棄される
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if let workingTimer = self.timer {
            workingTimer.invalidate()
        }
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        scrollView.isPagingEnabled = true
        scrollView.alwaysBounceHorizontal = true
 //scrollViewのサイズ指定
        scrollView.contentSize = CGSize(width: view.frame.size.width * 3, height: view.frame.size.height / 2)
        
    }
    
    //MARK: - 関数等
    @objc func didTapDone() {
        print("tapされたー")
    }
    
    
    // UIImageViewを生成
    func createImageView(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat, image: Photo) -> UIImageView {
        let imageView = UIImageView(frame: CGRect(x: x, y: y, width: width, height: height))
        let image = UIImage(systemName:  image.imageName)
        imageView.image = image
        return imageView
    }
    
    // photoListの要素分UIImageViewをscrollViewに並べる
    func setUpImageView() {
        for i in 0 ..< self.photoList.count {
            let photoItem = self.photoList[i]
            let imageView = createImageView(x: 0, y: 0, width: self.scrollView.frame.size.width, height: self.scrollView.frame.size.height , image: photoItem)
             
            imageView.translatesAutoresizingMaskIntoConstraints = false
            imageView.backgroundColor = .gray
            
            scrollView.addSubview(imageView)
            //ここポイントview.frame.size.width * CGFloat(i)　でスクロールするたびにcenterXAnchorをずらしてる
            imageView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor,constant: view.frame.size.width * CGFloat(i)).isActive = true
            imageView.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor).isActive = true
            //大きさ等
            imageView.widthAnchor.constraint(equalTo: scrollView.widthAnchor,constant:  -20).isActive = true
            imageView.heightAnchor.constraint(equalTo: scrollView.heightAnchor,constant: -20).isActive = true
        }
        
    }
    
         // offsetXの値を更新することページを移動
    @objc func scrollPage() {
        // 画面の幅分offsetXを移動
        self.offsetX += self.view.frame.size.width
        // 3ページ目まで移動したら1ページ目まで戻る
        if self.offsetX < self.view.frame.size.width * 3 {
            UIView.animate(withDuration: 0.3) {
                self.scrollView.contentOffset.x = self.offsetX
            }
        } else {
            UIView.animate(withDuration: 0.3) {
                self.offsetX = 0
                self.scrollView.contentOffset.x = self.offsetX
            }
        }
    }
    
}


//MARK: - UIScrollViewDelegate
extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // scrollViewのページ移動に合わせてpageControlの表示も移動
        self.pageControl.currentPage = Int(self.scrollView.contentOffset.x / self.scrollView.frame.size.width)
        // offsetXの値を更新
        self.offsetX = self.scrollView.contentOffset.x
    }
    
    
}


```
##UIViewの制約Extension
```swift
import UIKit

extension UIView {
    
    func anchor(top: NSLayoutYAxisAnchor?,
                leading: NSLayoutXAxisAnchor?,
                bottom: NSLayoutYAxisAnchor?,
                trailing: NSLayoutXAxisAnchor?,
                padding: UIEdgeInsets = .zero,
                size: CGSize = .zero) {
        translatesAutoresizingMaskIntoConstraints = false
        
        if let top = top {
            topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true
        }
        
        if let leading = leading {
            leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true
        }
        
        if let bottom = bottom {
            bottomAnchor.constraint(equalTo: bottom, constant: -padding.bottom).isActive = true
        }
        
        if let trailing = trailing {
            trailingAnchor.constraint(equalTo: trailing, constant: -padding.right).isActive = true
        }
        
        if size.width != 0 {
            widthAnchor.constraint(equalToConstant: size.width).isActive = true
        }
        
        if size.height != 0 {
            heightAnchor.constraint(equalToConstant: size.height).isActive = true
        }
    }
}

```
##完成イメージ
![オートスクロール.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1679562/c434b54a-60d9-6b14-5362-8c1898a9fb9a.gif)

##終わりに
もっといい方法あるはずｗ
誰かの参考になれば幸いです
Qiitaさんいつもお世話になってるので感謝
間違えてるところ等ありましたら教えてくださいー
##参考
https://qiita.com/ynakaDream/items/960899183c38949c2ab0

https://www.hfoasi8fje3.work/entry/2019/02/20/233607

https://stackoverflow.com/questions/48804229/how-do-i-have-to-modify-my-uiview-extension-if-i-wanted-to-animate-the-auto-layo

https://useyourloaf.com/blog/easier-scrolling-with-layout-guides/

https://developer.apple.com/documentation/uikit/uiscrollview/2865772-framelayoutguide