iOS

Floating button 만들기 in ScrollView

삼쓰 웅쓰 2019. 12. 10. 11:00
728x90

화면 Scroll에 상관없이 계속해서 떠있는, 흔히 말하는 floatring 버튼을 만드는 방법을 알아봅시다.


 

화면에 항상 떠있는 floating button을 만들고 싶다면,
autoLayout을 잡을 때 scrollView의 frameLayoutGuide 를 이용하면 됩니다.
항상 화면에 보이는 프레임의 layout을 따르겠다는 의미입니다.

이와 반대 개념으로 스크롤이 되어야 하는 뷰는 contentLayoutGuide 를 이용합니다.
스크롤 뷰 안의 내용 content의 layout을 따르겠다는 의미입니다.
즉, 스크롤이 되어지는 부분이 되겠죠?

scrollView 바로 밑에는 scrollView와 크기가 같은
contentView 가 contentLayoutGuide에 맞춰서 추가되고 그 밑에 view들이 추가되는 구조인데요,

스크롤 X
--> autolayout을 scrollView의 frameLayoutGuide에 맞춰주고,

스크롤 O
--> contentView의 layout에 맞춰주면 됩니다.

추가로! contentView 에 wight 또는 height 를 scrollView의 크기와 맞춰줘야 자연스럽게 스크롤 할 수 있습니다.
세로 스크롤이 필요하다면, cotentView 세로로 계속 길어야 하므로 height은 두고 width를 맞춰줍니다.
가로 스크롤이 필요하다면, 반대로 가로로 계속 길어야 하므로 width는 두고 height을 맞춰줍니다.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        contentView.addSubview(floatingButton)
        contentView.addSubview(testLabel)
        
        NSLayoutConstraint.activate([
            
            // 스크롤 뷰 추가
            scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            
            // 화면에 계속 보여지도록 frameLayout에 맞춰 floatingButton 추가
            floatingButton.bottomAnchor.constraint(equalTo: scrollView.frameLayoutGuide.bottomAnchor, constant: -30),
            floatingButton.trailingAnchor.constraint(equalTo: scrollView.frameLayoutGuide.trailingAnchor, constant: -30),
            
            // 스크롤 될 수 있도록 contentLayout에 맞춰 contentView 추가
            contentView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
            contentView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            contentView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
            
            // 세로 스크롤이 필요할 땐 width 를 맞춰주고
            // 가로 스크롤이 필요할 땐 height 를 맞춰준다.
            contentView.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor, multiplier: 1),
            //contentView.heightAnchor.constraint(equalTo: scrollView.frameLayoutGuide.heightAnchor, multiplier: 1),
            
            // 스크롤을 테스트 하기 위해 height을 크게 주고 label 추가
            testLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor, constant: 0),
            testLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0),
            testLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0),
            testLabel.heightAnchor.constraint(equalToConstant: 1500)
        ])
    }

    let scrollView: UIScrollView = {
        let scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        return scrollView
    }()
    
    let contentView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()
    
    let testLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = "스크롤 중 . . ."
        label.backgroundColor = .red
        label.textAlignment = .center
        return label
    }()

    let floatingButton: UIButton = {
        let button = UIButton(type: .system)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle("Floating", for: .normal)

        return button
    }()
}

 

이렇게하면
다음과 같은 결과를 얻을 수 있습니다 :)

 

 

 

감사합니다!

 

참고

How to Make a UIButton fix at UIScrollView?