본문 바로가기
IOS

Swift StoryBoard UICollectionView,UIPageControl를 이용하여 배너 만들기

by 일용직 코딩노동자 2023. 4. 25.
728x90
반응형

이번 게시글은 안드로이드에서 사용하는 ViewPager 같은 느낌의 녀석입니다.

 

인디케이터까지 포함하여 만들어보도록 하겠습니다.

 

보통 흔히 배너광고같은걸 넣을때 많이 쓰시는데요 차근차근 해보겠습니다.

 

Collection View를 하나 스토리보드에 넣어주세요.

대충 위에서10 좌우 16 높이 168로 지정해줬습니다.

 

여기 이 네모박스가 Collection View Cell인데요

좀 보기편하게 늘려줄게요

 

그리고 이 cell안에 이미지뷰를 하나 넣어주겠습니다.

 

전부다 0으로 걸어줬어요

이런식으로 이미지가 들어가있습니다.

 

BannerCell이라는 클래스를 하나 만들어주세요.

 

import Foundation
import UIKit

class BannerCell : UICollectionViewCell{
    
}

 

그리고 여기

Collection View Cell을 클릭하시면 오른쪽 상단에

 

Class를 방금만든 클래스를 지정해주시구요 Inherit Module From Target를 체크해주세요

보통 클래스 지정 후 엔터치시면 바로 적용됩니다.

 

Identifier도 같은이름으로 정의해줍니다.

이미지뷰를 BannerCell에 IBOutlet 연결해줍니다.
Ctrl + 마우스 드래그

 

다시 메인 뷰컨으로 돌아오셔서, UICollectionView도 IBOutlet 연결해줍니다. 같은 방식이에요!

이름은 bannerView로 설정했습니다.

 

그다음에 인디케이터도 넣어주겠습니다.

 

Page Control을 찾아서 넣어주세요.

노란놈이 지금 인디케이터 입니다.

 

가운데를 우선 잡아줍니다.

 

이제 소스로 돌아오면

 

    @IBOutlet weak var bannerView: UICollectionView!
    var nowPage = 0
    var banneryList = [String]()
    @IBOutlet weak var indicator: UIPageControl!

이렇게 현재 페이지를 나타낼 nowPage변수와 이미지 리스트를 담을 bannerList를 선언했습니다.

 

저는 이미지url을 API로 받아와서 저장할거라서 배열이 String이고 내부 이미지를 로드하실 계획이라면

 

UIImage로 자료형을 잡아주시면 됩니다.

 

viewDidLoad에서

 

self.bannerView.layer.cornerRadius = 4
self.bannerView.layer.borderWidth = 1
self.view.bringSubviewToFront(self.indicator)
self.indicator.numberOfPages = self.banneryList.count
self.indicator.currentPage = 0
self.indicator.currentPageIndicatorTintColor = 인디케이터 선택 된 컬러
self.indicator.pageIndicatorTintColor = 인디케이터 선택 안된 컬러

//bannerList에 append하는 과정이 필요해요
self.bannerList.append(이미지 혹은 url)

self.bannerView.delegate = self
self.bannerView.dataSource = self
self.autoBanner()

모서리를 둥글게 만들어주고 인디케이터를 맨앞으로 땡겨서 보여지도록 합니다.

대리자도 설정해줍니다.

컬러는 본인의 입맛대로 !!

 

그다음에 extension 해줍니다.

 

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        //여기서는 배너 클릭이벤트 처리
        print("클릭된 인덱스 : ",nowPage)
    }
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>){
        //여기서는 왼쪽 슬라이드인지 오른쪽 슬라이드인지 파악
        if velocity.x > 0 {
            //오른쪽 슬라이드
            self.nowPage += 1
        }
        else if velocity.x < 0 {
            //왼쪽 슬라이드
            self.nowPage -= 1
            if self.nowPage < 0 {
                self.nowPage = 0
            }
        }
        //현재 위치에따라 인디케이터도 변경
        self.indicator.currentPage = nowPage
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.banneryList.count
    }
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        //여기서 이미지를 로드
        let cell = bannerView.dequeueReusableCell(withReuseIdentifier: "BannerCell", for: indexPath) as! BannerCell
        /////////////////////url로 이미지를 로드하는경우/////////////////////
        do{
            if let url = URL(string: banneryList[indexPath.row]) {
                DispatchQueue.global().async{ [weak self] in
                    if let data = try? Data(contentsOf: url){
                        if let image = UIImage(data: data){
                            DispatchQueue.main.async {
                                cell.bannerImg.image = image
                            }
                        }
                    }
                }
            }
            return cell
        }
        catch{
            return cell
        }
        /////////////////////url로 이미지를 로드하는경우/////////////////////
        
        ///////////////////일반 내부 이미지를 로드하는 경우////////////////////
        cell.imgView.image = banneryList[indexPath.row]
        return cell
        ///////////////////일반 내부 이미지를 로드하는 경우////////////////////
        
        
    }
    
    //컬렉션뷰 사이즈 설정
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: bannerView.frame.size.width  , height:  bannerView.frame.height)
    }
    
    //자동 배너움직임
    func autoBanner() {
       let _: Timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { (Timer) in
           self.nowPage += 1
           if self.nowPage > self.banneryList.count - 1{
               self.nowPage = 0
           }
           self.bannerView.scrollToItem(at: NSIndexPath(item: self.nowPage, section: 0) as IndexPath, at: .right, animated: true)
           self.indicator.currentPage = self.nowPage
       }
   }

대략적인 주석이 있으니 참고하시면 어떤상황에 호출되는 녀석들인지 감이 오실거에요.

 

url로 이미지로드하는것과, 일반 이미지를 로드하는 코드는 주석으로 분리되어있으니 원하시는걸 골라서 사용하시면되요.

 

추가적으로 UICollectionView자체적으로 인디케이터가 존재하긴 합니다.

 

해당 인디케이터를 지우고싶으시면

 

요거 체크해서 해주시면 됩니당.

 

 

이렇게 하시면 배너광고가 완성됩니다!

728x90
반응형

댓글