UIScrollView로 가로 스크롤 메뉴를 만들어 보세요.

6480 단어 iOS
안녕하십니까. iOS Advente Calendar가 21일째입니다.
흔한 가로 스크롤 메뉴를 만들었다는 이야기.
좀 세련된 UI를 설치할 때는 항상 프로그램 라이브러리에 의존하기 쉽다고 생각합니다.
제가 직접 설치해보면 의외로 간단하니까 소개해 드릴게요.
완성품은 이런 느낌이에요.
적절하게 스크롤해도 지정할 태그가 자동으로 중심으로 이동합니다.

이렇게 어려워하는 사람을 향한 이야기다.

개요


여러 개의 가로 스크롤 메뉴가 설치되어 있을 수 있습니다. 이번에는 UIScrollView와 UIlabel을 사용했습니다.
우선 메뉴의 외관을 만들고 좋은 곳에 정지 스크롤 바를 설치하고 싶습니다.

겉모양을 만들어 보세요.


일단 스토리보드.


메뉴를 놓고 싶은 곳에 UIScrollView를 두세요.
기본적으로 너비와 화면의 너비가 잘 어울린다.
너는 세로로 하는 것을 좋아한다. 나는 60을 원한다.
그런 다음 UIScrollView를 코드에 연결합니다.

다음은 ScrollView의 UIlabel 출석체크.


다음으로 메뉴와 레이블이 있는 UIlabel을 준비합니다.
먼저 스크롤뷰 오른쪽 끝에 첫 번째 UIlabel을 호명합니다.
그리고 끊임없이 오른쪽으로 옮긴다.
이렇게 되면 먼저 스크롤할 수 있는 메뉴가 나온다.
@IBOutlet weak var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()

    let titles = ["月","火","水","木","金","土","日"] //タブのタイトル

    //タブの横幅
    let tabLabelWidth:CGFloat = 100
    //タブの縦幅(UIScrollViewと一緒にします)
    let tabLabelHeight:CGFloat = scrollView.frame.height

    //タブのx座標.0から始まり,少しずつずらしていく.
    var originX:CGFloat = 0
    //titlesで定義したタブを1つずつ用意していく
    for title in titles {
        //タブになるUILabelを作る
        let label = UILabel()
        label.textAlignment = .center
        label.frame = CGRect(x:originX, y:0, width:tabLabelWidth, height:tabLabelHeight)
        label.text = title

        //scrollViewにぺたっとする
        scrollView.addSubview(label)

        //次のタブのx座標を用意する
        originX += tabLabelWidth
    }

    //scrollViewのcontentSizeを,タブ全体のサイズに合わせてあげる(ここ重要!)
    //最終的なoriginX = タブ全体の横幅 になります
    scrollView.contentSize = CGSize(width:originX, height:tabLabelHeight)

}

느낌이 좋은 스크롤 바를 만들어 보세요.


이어 지정된 라벨에 편안한 스크롤 바를 설치한다.

UIScrollView의 Delegate 지정


먼저 scrollView의 Delegate를 지정합니다.
class ViewController: UIViewController, UIScrollViewDelegate {

@IBOutlet weak var scrollView: UIScrollView!    
@IBOutlet weak var weekdayLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView.delegate = self

탭 위치에서 정지된 위치에서 줄 준비하기


그리고 빠르게 멈출 수 있는 파란색 선을 준비하세요.
Storyboard에서scrollView의 바로 아래, 화면의 중심, 너비 100(라벨과 동일), 높이 3의 View를 만들면 OK입니다.

드디어 본론입니다.


그러면 UIScrollView의 Delegate를 사용하여 빠르게 멈추는 스크롤 바를 만듭니다.
방금 올린 소스 코드에서 변경된 부분도 있으니 전체 소스 코드를 넣으세요.
import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {

    @IBOutlet weak var scrollView: UIScrollView!

    //一度だけメニュー作成をするためのフラグ
    var didPrepareMenu = false

    //タブの横幅
    let tabLabelWidth:CGFloat = 100

    //viewDidLoad等で処理を行うと
    //scrollViewの正しいサイズが取得出来ません
    override func viewDidLayoutSubviews() {

        //viewDidLayoutSubviewsはviewDidLoadと違い
        //何度も呼ばれてしまうメソッドなので
        //一度だけメニュー作成を行うようにします
        if didPrepareMenu { return }
        didPrepareMenu = true

        //scrollViewのDelegateを指定
        scrollView.delegate = self

        //タブのタイトル
        let titles = ["月","火","水","木","金","土","日"] //タブのタイトル

        //タブの縦幅(UIScrollViewと一緒にします)
        let tabLabelHeight:CGFloat = scrollView.frame.height

        //右端にダミーのUILabelを置くことで
        //一番右のタブもセンターに持ってくることが出来ます
        let dummyLabelWidth = scrollView.frame.size.width/2 - tabLabelWidth/2
        let headDummyLabel = UILabel()
        headDummyLabel.frame = CGRect(x:0, y:0, width:dummyLabelWidth, height:tabLabelHeight)
        scrollView.addSubview(headDummyLabel)

        //タブのx座標.
        //ダミーLabel分,はじめからずらしてあげましょう.
        var originX:CGFloat = dummyLabelWidth
        //titlesで定義したタブを1つずつ用意していく
        for title in titles {
            //タブになるUILabelを作る
            let label = UILabel()
            label.textAlignment = .center
            label.frame = CGRect(x:originX, y:0, width:tabLabelWidth, height:tabLabelHeight)
            label.text = title

            //scrollViewにぺたっとする
            scrollView.addSubview(label)

            //次のタブのx座標を用意する
            originX += tabLabelWidth
        }

        //左端にダミーのUILabelを置くことで
        //一番左のタブもセンターに持ってくることが出来ます
        let tailLabel = UILabel()
        tailLabel.frame = CGRect(x:originX, y:0, width:dummyLabelWidth, height:tabLabelHeight)
        scrollView.addSubview(tailLabel)

        //ダミーLabel分を足して上げましょう
        originX += dummyLabelWidth

        //scrollViewのcontentSizeを,タブ全体のサイズに合わせてあげる(ここ重要!)
        //最終的なoriginX = タブ全体の横幅 になります
        scrollView.contentSize = CGSize(width:originX, height:tabLabelHeight)
    }

    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        guard scrollView == self.scrollView else { return }

        //微妙なスクロール位置でスクロールをやめた場合に
        //ちょうどいいタブをセンターに持ってくるためのアニメーションです

        //現在のスクロールの位置(scrollView.contentOffset.x)から
        //どこのタブを表示させたいか計算します
        let index = Int((scrollView.contentOffset.x + tabLabelWidth/2) / tabLabelWidth)
        let x = index * 100
        UIView.animate(withDuration: 0.3, animations: {
            scrollView.contentOffset = CGPoint(x:x, y:0)
        })
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        guard scrollView == self.scrollView else { return }

        //これも上と同様に

        let index = Int((scrollView.contentOffset.x + tabLabelWidth/2) / tabLabelWidth)
        let x = index * 100
        UIView.animate(withDuration: 1.0, animations: {
            scrollView.contentOffset = CGPoint(x:x, y:0)
        })
    }    
}   

총결산


이런 애니메이션을 만들면 좌표의 계산과 두뇌가 좀 쓸모가 있지만 만들기에는 의외로 간단하다.
나는 약간의 노력을 통해 응용 프로그램의 패션도가 크게 증가할 것이라고 생각한다. 반드시 시험해 보세요.

최후


시간 초과네요, 미안해요.
급하게 썼기 때문에 이해하기 어려운 부분이 있을 것 같은데,
모든 소스 코드가 업로드되었습니다. 읽어 주십시오. (토하좌)
그럼 메리 크리스마스

좋은 웹페이지 즐겨찾기