TableViewをスクロールでUIViewを上下に移動させる

#今回の内容
<img width="150" alt="17471A8A-866B-4A98-ADE2-650F96D9A276_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/945fcba0-93c8-8b04-9f67-d226ba00289c.jpeg">

#機能説明
TableViewをスクロールしている間は、画面の下にある横長のUIViewを見えない位置に移動させる。

#コードと簡単解説

##スクロールでUIViewを移動させる

* 移動させる横長のUIViewを作成

```Swift:UIView 
var moveView = UIView()

           ~~~一部省略~~~

moveView.frame = CGRect(x: view.frame.minX + 10, y: view.frame.maxY - (view.frame.maxY / 5), width: view.frame.size.width - 20, height: view.frame.size.height / 15)
        
        moveView.layer.cornerRadius = 30.0
        moveView.backgroundColor = .tertiarySystemGroupedBackground
        
        moveView.layer.shadowOffset = CGSize(width: 10, height: 10)
        moveView.layer.shadowOpacity = 0.5
        moveView.layer.shadowRadius = 7
        
        view.addSubview(moveView)
```
*  スクロールが開始された時に、画面の一番下に`moveView`を移動させます。

```Swift:ScrollView
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

        if moveView.frame.origin.y == view.frame.maxY - (view.frame.maxY / 7){

            UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY - self.moveView.frame.height}, completion: nil)

        }
    }
```

* スクロールをしている時に、`contentOffset.y > 0`なら一番下に表示してある`moveView`を画面から見えない位置に移動します。

```Swift:ScrollView
func scrollViewDidScroll(_ scrollView: UIScrollView) {

        if tableView.contentOffset.y > 0{

            UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY}, completion: nil)

        }
    }
```

* スクロールをやめる時に指が画面から離れた時に呼ばれています。
* スクロールの余力でTableViewがスクロールしない時に、下からUIViewを元の位置に戻します。

```Swift:ScrollView
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        
        UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY - (self.view.frame.maxY / 7)}, completion: nil)
        
    }
```

* スクロールが完了された時に、`moveView`を元の位置に戻します。

```Swift:ScrollView
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

        if moveView.frame.origin.y == self.view.frame.maxY{

            UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY - (self.view.frame.maxY / 7)}, completion: nil)

        }
    }
```

#全てのコード
```Swift:ViewController
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    
    var moveView = UIView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.delegate = self
        tableView.dataSource = self
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        moveView.frame = CGRect(x: view.frame.minX + 10, y: view.frame.maxY - (view.frame.maxY / 7), width: view.frame.size.width - 20, height: view.frame.size.height / 15)
        
        moveView.layer.cornerRadius = 30.0
        moveView.backgroundColor = .tertiarySystemGroupedBackground
        
        moveView.layer.shadowOffset = CGSize(width: 10, height: 10)
        moveView.layer.shadowOpacity = 0.5
        moveView.layer.shadowRadius = 7
        
        view.addSubview(moveView)
        
    }


}

extension ViewController:UITableViewDelegate,UITableViewDataSource {
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return 40
        
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        
        cell.textLabel?.text = String(indexPath.row)
        
        return cell
        
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

        if moveView.frame.origin.y == view.frame.maxY - (view.frame.maxY / 7){

            UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY - self.moveView.frame.height}, completion: nil)

        }

    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {

        if tableView.contentOffset.y > 0{

            UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY}, completion: nil)
         
        }

    }
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        
        UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY - (self.view.frame.maxY / 7)}, completion: nil)
        
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

        if moveView.frame.origin.y == self.view.frame.maxY{

            UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut, animations: {self.moveView.frame.origin.y =  self.view.frame.maxY - (self.view.frame.maxY / 7)}, completion: nil)
       
        }
    }
      
}
```

#終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。