꾸준히 안타치기

탭바 커스터마이징(스토리보드) 본문

iOS/기본편 | 실전편 -꼼꼼한재은씨

탭바 커스터마이징(스토리보드)

글자줍기 2022. 1. 30. 17:26
반응형

프로젝트를 생성하고, 뷰컨트롤러가 있는 상태에서 임베디드해                        TabbarController를  생성한다.

뷰컨트롤러를 2개더 추가하고, 탭바컨트롤러에서 Ctrl클릭후 뷰컨트롤러로 연결한다. Relationship Segue ->view controllers

각각의 뷰컨트롤러에 클래스를 생성해 연결한다. 뷰컨1, 뷰컨2, 뷰컨3...

탭전환시 화면을 식별할수 있도록 뷰 컨트롤러에 레이블을 추가한다.

 sizeToFit메소드와 center속성 설정 구문을 함께 사용할 경우, 객체의 center속성 설정은 항상 sizeToFit메소드 호출후에 처리하는것이 좋다. 이유는 객체의 크기가 정해진 다음에 center값을 정하는것이 안전하기 때문

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        //1.타이틀레이블 생성
        let title = UILabel(frame: CGRect(x: 0, y: 100, width: 100, height: 30))

        //2.타이틀 레이블속성설정
        title.text = "첫번째탭"
        title.textColor = .red
        title.textAlignment = .center
        title.font = UIFont.boldSystemFont(ofSize: 14)

        //콘텐츠 내용에 맞게 레이블 크기 변경
        title.sizeToFit()

        //x축의 중앙에 오도록 설정
        title.center.x = self.view.frame.width / 2

        //수퍼뷰에 추가
        self.view.addSubview(title)
    }
}

 

Resources폴더를 만들고, 탭바에 추가할 이미지를 넣는다. 이때  옵션에 Copy items if needed에 체크한다.

- Copy items if needed 옵션은 파일을 실제 프로젝트 내에도 복사함을 의미한다.


탭바의 이미지와 색상 커스터마이징하기 

탭바아이템뷰컨트롤러에서 self.tabBarItem속성을 이용해 직접 참조할수 있다. (현재 뷰컨트롤러 지정된 탭바 아이템만 접근가능)

- 뷰컨트롤러에서 직접 참조할수 있는 것은 탭바컨트롤러와, 탭바 아이템이다. (탭바X) 탭바를 참조하기 위해서는 반드시 탭바컨트롤러를 거쳐야한다.

탭바 컨트롤러 -> 탭바를 통해서도 탭바아이템에 접근할수 있다. 이때는 인덱스번호를 변경하면 모든 탭바아이템에 접근이 가능하다.

 

탭바에 관련된 코드는 뷰컨트롤러의 viewDidLoad의 여부와 상관없이 실행할수 있는 곳에서 작성하는것이좋다.

- iOS 13부터 하나의 앱에 여러개의 윈도우가 동시에 사용될수 있게 됨에 따라 UI라이프사이클을 전담해줄 클래스가 필요해졌고, 이를 위해 추가된 클래스가 SceneDelegate이다.

- 반면 AppDelegate클래스는 UI관리 역할에서 벗어나 프로세스 자체의 라이프사이클을 관리하는 역할에 집중하게 됨. 앱의 데이터 구조초기화나, 푸시알림등의 서비스 초기화, 앱 밖에서 발생한 알림에 대응하는 등의 일을 전담한다.

 

SceneDelegate클래스의 scene(_:willConnectTo:options)메소드에 코드를 작성한다.

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?
    
    // 탭바 설정작성
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let _ = (scene as? UIWindowScene) else { return }
        //루트뷰 컨트롤러를 UITabBarController로 캐스팅한다.
        if let tbC = self.window?.rootViewController as? UITabBarController {
            
            //탭바에서 탭바 아이템 배열을 가져온다.
            if let tbItems = tbC.tabBar.items {
                //탭바 아이템에 커스텀 이미지를 등록한다.
//                tbItems[0].image = UIImage(named: "calendar")
//                tbItems[1].image = UIImage(named: "file-tree")
//                tbItems[2].image = UIImage(named: "photo")
                
                // 탭바 아이템에 커스텀 이미지를 등록한다.2
                // 원본이미지 설정을 위해 UI이미지렌더링을 해주어야함.
                tbItems[0].image = UIImage(named: "designbump")?.withRenderingMode(.alwaysOriginal)
                tbItems[1].image = UIImage(named: "rss")?.withRenderingMode(.alwaysOriginal)
                tbItems[2].image = UIImage(named: "facebook")?.withRenderingMode(.alwaysOriginal)
                
                // 탭 바 아이템 전체를 순회하면서 selectedImage 속성에 이미지를 설정한다.
                // selectedImage는 탭바아이템이 선택되었을때의 이미지이다.
                for tbItem in tbItems {
                    let image = UIImage(named: "checkmark")?.withRenderingMode(.alwaysOriginal)
                    tbItem.selectedImage = image
                }
                
                //탭바 아이템에 타이틀을 설정한다.
                tbItems[0].title = "calendar"
                tbItems[1].title = "file"
                tbItems[2].title = "photo"
                
            }
//            // ⑤ 탭 바 아이템의 이미지 색상을 변경한다.
//            tbC.tabBar.tintColor = .white // 선택된 탭 바 아이템의 색상
//            tbC.tabBar.unselectedItemTintColor = .gray // 선택되지 않은 나머지 탭 바 아이템의 색상
//
//            // ⑥ 탭 바에 배경 이미지를 설정한다.
//            tbC.tabBar.backgroundImage = UIImage(named:"menubar-bg-mini")
        }
    }
}

탭바 기본이미지, 선택됬을때 이미지를 모두 추가해주어야한다.

 

탭바 아이템 타이틀을 커스터마이징 해보자 / 1.직접 속성설정하는 방법

-직접 속성설정하는 방법과, 외형프록시 객체를 통해 커스터마이징 하는 방법이 있다.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?
    
    // 탭바 설정작성
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let _ = (scene as? UIWindowScene) else { return }
        //루트뷰 컨트롤러를 UITabBarController로 캐스팅한다.
        if let tbC = self.window?.rootViewController as? UITabBarController {
            
            //탭바에서 탭바 아이템 배열을 가져온다.
            if let tbItems = tbC.tabBar.items {
                //탭바 아이템에 커스텀 이미지를 등록한다.

                // 탭바 아이템에 커스텀 이미지를 등록한다.
                tbItems[0].image = UIImage(named: "designbump")?.withRenderingMode(.alwaysOriginal)
                tbItems[1].image = UIImage(named: "rss")?.withRenderingMode(.alwaysOriginal)
                tbItems[2].image = UIImage(named: "facebook")?.withRenderingMode(.alwaysOriginal)
                
                // 탭 바 아이템 전체를 순회하면서 selectedImage 속성에 이미지를 설정한다.
                for tbItem in tbItems {
                    let image = UIImage(named: "checkmark")?.withRenderingMode(.alwaysOriginal)
                    tbItem.selectedImage = image
                    //탭바 아이템별 텍스트 색상 속성을 설정한다.
                    tbItem.setTitleTextAttributes([.foregroundColor:UIColor.gray], for: .disabled)
                    tbItem.setTitleTextAttributes([.foregroundColor:UIColor.red], for: .selected)
                    //전체 아이템의 폰트 크기를 설정한다.
                    tbItem.setTitleTextAttributes([.font:UIFont.systemFont(ofSize: 15)], for: .normal)
                }
                
                //탭바 아이템에 타이틀을 설정한다.
                tbItems[0].title = "calendar"
                tbItems[1].title = "file"
                tbItems[2].title = "photo"
            }
        }
    }
    
    }

탭바 아이템 타이틀을 커스터마이징 해보자 /  2.외형프록시 객체 사용방법

- 코코아 터치프레임워크는 전체를 순회하지 않고도 공통으로 속성을 적용할 수 있도록 세련된방법을 제공한다.

-그것이 바로 외형프록시 객체이다. 외형 프록시 객체는 화면 요소별 속성을 공통으로 적용할 수 있는 객체이다.

- 외형프록시 객체에 속성을 설정해두면, 해당타입으로 생성된 모든 객체에 해당 속성이 적용된다.

- 아이템타이틀색상,폰트크기,탭바 속성 등을 외형프록시 객체를 통해 설정할 수 있다.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?
    
    // 탭바 설정작성
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let _ = (scene as? UIWindowScene) else { return }
        //루트뷰 컨트롤러를 UITabBarController로 캐스팅한다.
        if let tbC = self.window?.rootViewController as? UITabBarController {
            
            //탭바에서 탭바 아이템 배열을 가져온다.
            if let tbItems = tbC.tabBar.items {
                //탭바 아이템에 커스텀 이미지를 등록한다.

                // 탭바 아이템에 커스텀 이미지를 등록한다.
                tbItems[0].image = UIImage(named: "designbump")?.withRenderingMode(.alwaysOriginal)
                tbItems[1].image = UIImage(named: "rss")?.withRenderingMode(.alwaysOriginal)
                tbItems[2].image = UIImage(named: "facebook")?.withRenderingMode(.alwaysOriginal)
                
                // 탭 바 아이템 전체를 순회하면서 selectedImage 속성에 이미지를 설정한다.
                for tbItem in tbItems {
                    let image = UIImage(named: "checkmark")?.withRenderingMode(.alwaysOriginal)
                    tbItem.selectedImage = image
                
                }
                // 외형 프록시객체를 이용하여 아이템의 타이틀 색상과 폰트 크기를 설정한다.
                let tbItemProxy = UITabBarItem.appearance()
                tbItemProxy.setTitleTextAttributes([.foregroundColor:UIColor.red], for: .selected)
                tbItemProxy.setTitleTextAttributes([.foregroundColor:UIColor.gray], for: .disabled)
                tbItemProxy.setTitleTextAttributes([.font: UIFont.systemFont(ofSize: 15)],for: .normal)
                
                //탭바 아이템에 타이틀을 설정한다.
                tbItems[0].title = "calendar"
                tbItems[1].title = "file"
                tbItems[2].title = "photo"
                
            }
        }
    }
    }

 SceneDelegate 최종소스

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow?
    
    // 탭바 설정작성
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let _ = (scene as? UIWindowScene) else { return }
        //루트뷰 컨트롤러를 UITabBarController로 캐스팅한다.
        if let tbC = self.window?.rootViewController as? UITabBarController {
            
            //탭바에서 탭바 아이템 배열을 가져온다.
            if let tbItems = tbC.tabBar.items {
                //탭바 아이템에 커스텀 이미지를 등록한다.

                // 탭바 아이템에 커스텀 이미지를 등록한다.
                tbItems[0].image = UIImage(named: "designbump")?.withRenderingMode(.alwaysOriginal)
                tbItems[1].image = UIImage(named: "rss")?.withRenderingMode(.alwaysOriginal)
                tbItems[2].image = UIImage(named: "facebook")?.withRenderingMode(.alwaysOriginal)
                
                // 탭 바 아이템 전체를 순회하면서 selectedImage 속성에 이미지를 설정한다.
                for tbItem in tbItems {
                    let image = UIImage(named: "checkmark")?.withRenderingMode(.alwaysOriginal)
                    tbItem.selectedImage = image
                
                }
                // 외형 프록시객체를 이용하여 아이템의 타이틀 색상과 폰트 크기를 설정한다.
                let tbItemProxy = UITabBarItem.appearance()
                tbItemProxy.setTitleTextAttributes([.foregroundColor:UIColor.red], for: .selected)
                tbItemProxy.setTitleTextAttributes([.foregroundColor:UIColor.gray], for: .disabled)
                tbItemProxy.setTitleTextAttributes([.font: UIFont.systemFont(ofSize: 15)],for: .normal)
                
                //탭바 아이템에 타이틀을 설정한다.
                tbItems[0].title = "calendar"
                tbItems[1].title = "file"
                tbItems[2].title = "photo"
                
            }
        }
    }
    
    func sceneDidDisconnect(_ scene: UIScene) {
        // Called as the scene is being released by the system.
        // This occurs shortly after the scene enters the background, or when its session is discarded.
        // Release any resources associated with this scene that can be re-created the next time the scene connects.
        // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
    }
    
    func sceneDidBecomeActive(_ scene: UIScene) {
        // Called when the scene has moved from an inactive state to an active state.
        // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
    }
    
    func sceneWillResignActive(_ scene: UIScene) {
        // Called when the scene will move from an active state to an inactive state.
        // This may occur due to temporary interruptions (ex. an incoming phone call).
    }
    
    func sceneWillEnterForeground(_ scene: UIScene) {
        // Called as the scene transitions from the background to the foreground.
        // Use this method to undo the changes made on entering the background.
    }
    
    func sceneDidEnterBackground(_ scene: UIScene) {
        // Called as the scene transitions from the foreground to the background.
        // Use this method to save data, release shared resources, and store enough scene-specific state information
        // to restore the scene back to its current state.
    }
    
    
}
반응형
Comments