봄날은 갔다. 이제 그 정신으로 공부하자

코딩으로 가로 스크롤 뷰 만들기 본문

iOS Tip

코딩으로 가로 스크롤 뷰 만들기

길재의 그 정신으로 공부하자 2022. 4. 5. 22:22

이번 글에서는 가로 스크롤 뷰를 storyboard가 아닌 코딩으로 하는 방법에 대해 설명하도록 하겠습니다.

얼마 전 가로 스크롤 뷰 개발 미션이 있어 개발하려고 보니 이게 난감한게 아이템 갯수가 정해진 게 아니라 가변이더군요.

미션 내용을 정리해보면 아래와 같습니다.

  - 서버에서 많은 아이템의 수많큼 가변으로 보여져야 됨.

  - 가로 * 세로 100 * 40 사이즈로 보여져야 함

  - 사용자가 아이템을 선택해 아이템을 삭제할 수 있음.

 

그래서 이걸 어떻게 처리해야 하나 고민하다 직접 코딩해서 해결하기로 했고 결과물은 다음과 같습니다.

 

우선 아이템을 보여줄 View를 아래와 같이 생성해 줍니다.

미션에서는 조금 더 복잡하게 보여주지만 여기에서는 간략하게 UILabel 한개만 있다고 가정하겠습니다.

class MyItemView: UIView {
    @IBInspectable var topMargin : CGFloat = 0
    
    var lbName:UILabel?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupComponents()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        setupComponents()
    }
    
    private func setupComponents() {        
        lbName = UILabel(frame:CGRect(x:0, y:0, width:100, height:40))
        lbName?.textColor = .black
        lbName?.textAlignment = .center
        self.addSubview(lbName!)       
     }   
}

 

다음으로 MyItemView을 보여줄 스크롤 뷰 class를 만들어 줍니다.

UIView를 상속받은 MyScrollView class를 만들어 줍니다.

이 클래스에서는 스크롤 뷰에 MyItemView를 동적으로 생성해서 추가하고 해당 아이템 클릭 시 처리를 해주어야 하므로 아래와 같이 3개의 속성을 추가합니다.

var scrollView: UIScrollView?
var myItemViewList: [MyItemView] = []
var myItemList: [MyListItem] = []

그 다음으로 scrollView를 생성해주고

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

scrollView에 아이템을 추가하는 함수를 만들어 줍니다.

func addMyItems(items: [MyListItem]) {
    items.forEach { item in
        addMyItemView(name: item.name)
        myItemList.append(item)
    }
}

     

아이템 추가 시 아이템 클릭 시 처리 할 수 있도록 actionMyItem() 함수를 정의하고 UITapGestureRecognizer를 사용해 추가해 줍니다.

private func addMyItemView(name: String) {
    let posX = myItemList.count * 100
    let view: MyItemView = MyItemView(frame:CGRect(x:posX, y:0, width:100, height:40))
    view.lbName?.text = name
    view.tag = myItemList.count
    var tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(actionMyItem(_:)))
    view.addGestureRecognizer(tapRecognizer)
    view.isUserInteractionEnabled = true
        
    scrollView?.addSubview(view)
    myItemViewList.append(view)
    scrollView?.contentSize = CGSize(width: posX + 100, height: 40)
    
}

@objc private func actionMyItem(_ recognizer: UITapGestureRecognizer) {
    if let index = recognizer.view?.tag {      
        print("actionMyItem(\(index))")
        
        // 아이템 클릭 시 처리할 부분 추가
        ...
    }
}

전체 소스는 아래와 같습니다.

class MyScrollView: UIView {    
    @IBInspectable var topMargin : CGFloat = 0
    
    var scrollView: UIScrollView?
    
    var myItemViewList: [MyItemView] = []
    var myItemList: [MyItem] = []
    var prevIndex = -1
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupComponents()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        setupComponents()
    }
    
    private func setupComponents() {
    
        self.tag = CategoriesView.VIEW_TAG
        
        scrollView = UIScrollView(frame:CGRect(x:0, y:0, width:self.frame.width, height:self.frame.height))
        self.addSubview(scrollView!)
    }
    
    func addCategories(categories: [MenuCategoryListItem]) {
        categories.forEach { category in
            addCategoryView(name: category.cateNm)
            cagetoryItems.append(category)
        }
    }
        
    private func addMyItemView(name: String) {
        let posX = myItemList.count * 100
        let view: MyItemView = MyItemView(frame:CGRect(x:posX, y:0, width:100, height:40))
        view.lbName?.text = name
        view.tag = myItemList.count
        var tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(actionMyItem(_:)))
        view.addGestureRecognizer(tapRecognizer)
        view.isUserInteractionEnabled = true
        
        scrollView?.addSubview(view)
        myItemViewList.append(view)
        scrollView?.contentSize = CGSize(width: posX + 100, height: 40)
    }

    @objc private func actionMyItem(_ recognizer: UITapGestureRecognizer) {
        if let index = recognizer.view?.tag {      
            print("actionMyItem(\(index))")
        
            // 아이템 클릭 시 처리할 부분 추가
            ...
        }
    }
}

'iOS Tip' 카테고리의 다른 글

IOS 앱 디버깅 방지  (0) 2022.04.20
set, get, willSet, didSet  (0) 2022.04.13
배경이 투명한 ViewController 만들기  (0) 2022.03.30
이미지 라운드 처리하기  (0) 2022.03.25
5. SwiftUI Tutorial - animation  (0) 2022.03.16
Comments