[Swift5] TableView 만들기 (custom cell을 만들어 보기)


저의 경우 아이폰 개발을 하면서 TableView를 많이 사용하게 되었는데, 덕분에 많은 부분 깨닳음(??)이 있었습니다.

오늘은 간단하게(?) TableView를 만들고 입맛에 맞춰 Custom Cell을 만드는 방법을 알아보도록 하겠습니다. 


Storyboard 작업

자, 우선 프로젝트를 생성해주시고, Main.storyboard를 선택합니다.

 

그리고 Component 중 Table View를 화면에 드래그해서 추가해줍니다. 

화면에 Table View Component 추가

 

다음으로 Table View에 보일 Cell(Table View Cell)을 앞서 만든 Table View 내에 추가해줍니다.

Table View에 Table View Cell 추가

 

Table View Cell 내 Content View 내부의 원하시는 Component를 추가해줍니다.

(여기서는 예시로 Image View, Label, Button을 추가했습니다.(왼쪽부터 순서대로))

Table View Cell 내 Content View에 원하시는 Component를 추가합니다.

 

이제 View Controller에 연결된 Class(Source 단)로 이동합니다.

(연결된 Class 정보를 잘 모르시겠다면, 처음 기본적으로 생성된 Controller의 Class는 보통 ViewController.swift입니다. 좌측에서 ViewController.swift 파일을 선택하시거나, 하단의 이미지처럼 ViewController의 Class를 확인 후 이동해 주세요.)

 

여기까지 따라오셨다면, Storyboard에서 초기작업이 끝났습니다.

단, 완벽히 끝난건 아니고, 이후부터는 Class(Source)와 Storyboard(View)를 왔다갔다하시면서 작업을 해야합니다.

 

ViewController Class 작업

처음 생성된 ViewController

 

Table View를 이용하기 위해서는 이동하신 Controller에 Table View를 동작하기 위한 Class를 상속받아야 합니다.

여기서는 Table View의 기능을 처리할 delegate(대리자) - UITableViewDelegate와 Tablew View Cell등을 제어하여 데이터를 처리할 datasource(데이터 소스) - UITableViewDataSource를 상속해줘야 합니다.

(저는 extension(확장)하는 방식으로 진행했습니다.)

 - UITableViewDelegate : Table View에서 Cell을 선택하거나, 어떠한 기능을 처리

 - UITableViewDataSource : Table View에서 Cell을 보여주기 위해 Table View의 Row나 Section은 어떻게 구현을 할것이며, Cell은 어떻게 만들어줄 것인지를 제어

   -> UITableViewDataSource 내에는 필수(Required) 함수들이 있습니다.

   -> func tableView(func tableView(UITableView, numberOfRowsInSection: Int) -> Int

   -> func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell

   -> 위 두 함수가 그것이며, 각각 section내에 몇개의 row가 있는지, 각 index별 cell의 정보를 어떻게 담고 있는지를 알려주기 위한 함수입니다.(하단 그림 참조)

 

ViewController를 extension(확장)하여 UITableViewDataSource, UITableViewDelegate를 상속시켜줍니다.

 

UITableViewCell Class 작업

이제 위에서 선언한 필수 함수 내부에 code를 구현을 해야겠죠!

하지만, 그 전에 우리는 UITableViewCell을 Return해줄 Class의 생성이 필요합니다.

그래서 우선은 code의 구현은 잠시 미루고 Class를 생성해주기로 합시다!

Cocoa Touch Class를 선택한 상태로 Next

Cocoa Touch Class 선택 -> Next

 

Class의 이름을 지어주고, 상속받을 Class를 선택해줍니다.

(편의상 Class의 이름은 CustomCell로 지었으며, Return할 UITableViewCell의 Class를 생성하고 있으니 상속받을 Class는 UITableViewCell을 선택해줍니다. - 하단 이미지 참조)

UITableViewCell을 상속하는 CustomCell을 만들어줍니다.

 

생성된 CustomCell Class.

UITableViewCell을 상속받는 CustomCell의 생성이 완료되었습니다.

 

이제 다시 Main.storyboard로 이동하셔서 Cell과 위에서 만드신 CustomCell을 연결해주는 작업을 합니다.

CustomCell의 Class 연결

그리고 Table View Cell의 Identifier를 지정해줍니다.

(여기서는 편의상 customCell로 지정했습니다.)

Tablew View Cell의 Identifier 지정

 

마지막으로 Main.storyboard와 앞에서 생성한 CustomCell.swift 파일을 나란히 열어두고,

기존에 만든 Component(ImageView, Label, Button)을 CustomCell Class에 선언해줍니다.

선언 방식은 Component를 마우스 우클릭하신 상태로 CustomCell Class(.swift)파일로 옮기시면 됩니다. - 하단 이미지 참조

화살표처럼 Componet를 마우스 우클릭한 상태로 소스단으로 드래그

 

자! 여기까지 오셨다면 Table View에서 Return해줄 Table View Cell Class는 다 만들어준겁니다!

 

ViewController Class 작업

이제 기존에 열어두신 화면 그대로에서 CustomCell Class 쪽만 ViewController Class로 변경해줍니다.

이 후 미리 Main.storyboard에 생성한 Table View를 제어하기 위해 위 Componet 선언한 방식처럼 Class(ViewController.swift)쪽에 선언합니다.(마우스 우클릭 한 상태로 드래그)

Table View를 제어하기위해 ViewController에 선언해줍니다.

 

마지막으로 CustomCell에 보여줄 Data와 code 생성합니다.

(하단 이미지의 소스코드는 게시글 아래쪽으로 더 내려보시면 설명과 함께 다시 정리되어있습니다.)

이제 code를 추가합니다.

 

cellName = String 형식으로, 위에서 정의한 Table View Cell의 Identifier 입니다. 저는 편의상 "customCell"로 지정하였으므로 cellName에는 "customCell" 대입해주고 있습니다.

cellTitle = Array 타입으로, ImageView의 iamge 정보를 나타냅니다. 더불어 Label의 text에 image값을 String 형식으로 넣어주기 위한 변수입니다.

 

viewDidLoad 함수의 [tableView_custom.delegate = self]

 - 기존에 선언해둔 TableView - tableView_custom에 delegate를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDelegate의 정보를 대입합니다.)

viewDidLoad 함수의 [tableView_custom.dataSource = self]

 - 기존에 선언해둔 TableView - tableView_custom에 dataSource를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDataSource의 정보를 대입합니다.)

 

extension ViewController class의 [func tableView(func tableView(UITableView, numberOfRowsInSection: Int) -> Int] 함수

 - 화면에 보여줄 row의 갯수를 나타냅니다. 여기서는 cellTitle.count 이므로 선언된 cellTitle 변수에는 3개의 값이 들어 있으므로 3을 return하게 됩니다.

extionsion ViewController class의 [func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell] 함수

 - 화면에 보여줄 cell을 지정합니다. function내에는 cellName("customCell")의 customCell을 선언했고, 이 customCell에 있는 Component imageView_custom과 label_custom의 정보(이미지, 텍스트)를 변경해주고 있습니다. (즉, Cell 내부 이미지와 텍스트는 짝이 되어 보일겁니다.)

 

완성된 프로젝트 Run

이제 완성된 프로젝트를 실행해 봅시다!

아이폰 11 Simulator


ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView_custom: UITableView!
    let cellName:String = "customCell"
    let cellTitle : Array<String> = ["pencil.circle", "doc.circle", "bolt.circle"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        tableView_custom.delegate = self
        tableView_custom.dataSource = self
    }

}

 

extension ViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return cellTitle.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let customCell = tableView_custom.dequeueReusableCell(withIdentifier: cellName, for: indexPath) as! CustomCell

        customCell.imageView_custom.image = UIImage(systemName: cellTitle[indexPath.row])
        customCell.label_custom.text = cellTitle[indexPath.row]

        return customCell
    }
    
}

cellName = String 형식으로, 위에서 정의한 Table View Cell의 Identifier 입니다. 저는 편의상 "customCell"로 지정하였으므로 cellName에는 "customCell" 대입해주고 있습니다.

cellTitle = Array 타입으로, ImageView의 iamge 정보를 나타냅니다. 더불어 Label의 text에 image값을 String 형식으로 넣어주기 위한 변수입니다.

 

viewDidLoad 함수의 [tableView_custom.delegate = self]

 - 기존에 선언해둔 TableView - tableView_custom에 delegate를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDelegate의 정보를 대입합니다.)

viewDidLoad 함수의 [tableView_custom.dataSource = self]

 - 기존에 선언해둔 TableView - tableView_custom에 dataSource를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDataSource의 정보를 대입합니다.)

 

extension ViewController class의 [func tableView(func tableView(UITableView, numberOfRowsInSection: Int) -> Int] 함수

 - 화면에 보여줄 row의 갯수를 나타냅니다. 여기서는 cellTitle.count 이므로 선언된 cellTitle 변수에는 3개의 값이 들어 있으므로 3을 return하게 됩니다.

extionsion ViewController class의 [func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell] 함수

 - 화면에 보여줄 cell을 지정합니다. function내에는 cellName("customCell")의 customCell을 선언했고, 이 customCell에 있는 Component imageView_custom과 label_custom의 정보(이미지, 텍스트)를 변경해주고 있습니다. (즉, Cell 내부 이미지와 텍스트는 짝이 되어 보일겁니다.)

 

 

CustomCell.swift

import UIKit

class CustomCell: UITableViewCell {

    @IBOutlet weak var imageView_custom: UIImageView!
    @IBOutlet weak var label_custom: UILabel!
    @IBOutlet weak var button_custom: UIButton!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
        
    }

}

앞서 마우스 우클릭 드래그를 통해 선언해준 Componet 정보들이 담겨있습니다.

Cell 내부 ImageView -> imageView_custom

Cell 내부 Label -> label_custom

Cell 내부 Button -> button_custom


간단(?)하게 설명만 하려했더니 생각보다 길어져버렸네요;;;

스터디 하는 김에 겸사겸사 하긴했는데.. 내용이 너무 길어져버려서..;;;

혹시 이해안가시면 댓글 작성해주세요. 최대한 다시 설명드리겠습니다 ㅠㅠ

 

 

버전정보 (v1.0)

 - v1.0 2020.07.22 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Xcode] 에러해결 : Failed to register bundle identifier. The app identifier "~" cannot be registered to your development team because it is not available. Change your bundle identifier to a unique string to try again.


iOS개발을 하다보면 간혹 아래와 같은 문제를 만나볼 수 있습니다.

 

Showing All Messages

Failed to register bundle identifier. The app identifier "~" cannot be registered to your development team because it is not available. Change your bundle identifier to a unique string to try again.

 

위 에러에 대한 원인과 해결방안에 대해서 알아보도록 하겠습니다.


원인

또 에러..

에러만 뜨고 빌드 조차 진행이 안될건데, 해당 문제는 Bundle Identifier가 고유하지 않아 생기는 문제입니다.  (아마 이미 사용중인 경우가 거의일겁니다.)

 

 

해결

 

에러 메세지를 읽어보면 대충 이런 뉘앙스입니다.

bundle identifier의 등록을 실패했고, 앱의 identifier "~"를 사용할 수 없어 당신의 개발팀에 등록할 수 없으므로 , 당신의 bundle identifier를 고유한 문자열로 변경하고 다시 시도해보세요.

 

메세지처럼 Bundle Identifier를 변경해줌으로써 해결이 가능합니다.

(이미지의 inputbox부분을 고유한 Bundle Identifier로 변경)

 


위 에러.. 솔직히 어려운건아닌데,

저 푸릇푸릇한 개발 초보시절에는(지금도 초보지만..) 에러문장이 나와도 그냥 안되니까 당황해서 저거 하나가지고 엄청 시간잡아먹기도 했었습니다 ㅠㅠ (제가 바보라..)

그때 기억 생각나서 게시글 작성해보게되네요 ㅋㅋ;;

 

누군가에게는 도움이 되기를 바라면서..

 

 

버전정보 (v1.0)

 - v1.0 2020.07.21 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Xcode] 에러해결 : iPhone is not available


아침부터 끙끙 앓고 있던 문제였는데,

실제 아이폰을 연결해서 테스트를 진행하려보니 iPhone is not available가 뜨고 진행이 안되는 문제가 있었습니다.

 

알고보니 Xcode와 iOS 버전이 맞지않아 그러는거라고..

(정확히는 SDK버전.)

 

오전중 계속 잡은거 치고 해결방법은 단순했는데, 저는 이걸 해결하겠다고 시간을 잡아먹기만.. (.......)

역시 사람은 모르면 검색을 해봐야합니다 ㅋㅋㅋ (저는 왜 검색안하고 계속 맥미니를 껏다키고 폰의 usb도 빼고껴고를 반복을 했는지...)

 


원인

위에서 언급한것처럼 Xcode에 있는 SDK버전이 맞지 않아서 그렇습니다.

저의 경우 금요일날 퇴근전에 아이폰을 업데이트를 진행해놓고 나갔는데 (iOS 13.5 -> iOS 13.6) 이게 원인이 되었습니다. ㅠㅠ

반나절간 재접속시키고 폰 연결해제도해보고 별짓을..

 

해결

해결방법은 쉽습니다.

1. 에뮬레이터로 테스트를 하거나,

2. iOS버전을 낮추거나 (...)

3. 위 해결방법들보다는 그냥 Xcode의 버전을 올려주는게 정답이겠죠? 

 - 찾아보니 iOS 13.6을 사용하려면 Xcode의 버전을 11.6으로 올려줘야합니다.

 - 지금 제가 사용중인 버전은 11.5이므로 Xcode의 버전올림이 필요하네요.

 

이유는 모르겠지만, 자동업데이트가 안되나봅니다.. (분명 가능했던거같았는데...)

 

저의 경우 App Store에서 직접 찾아서 다운로드 버튼눌렀습니다.

** 설치 전 혹시 모를 충돌을 방지하기 위해 켜져있는 Xcode와 에뮬레이터 그리고 폰의 연결을 해제해주세요.

 

xcode를 검색해서 설치 진행!

 


흠.. 아무래도 앞으로는 개발 테스트중일때에는 폰의 업데이트는 최대한 보류하는걸로..ㅠㅠ

 

버전정보 (v1.0)

 - v1.0 2020.07.20 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Swift5] 에러해결 : unable to dequeue a cell with identifier ~


iOS 어플 개발 테스트 중 화면이 뜨지 않고 이러한 에러를 만날때가 있습니다.

unable to dequeue a cell with identifier ~

저의 경우 TableView를 건들다가 일어난 문제였는데요, 어렵지 않게 해결할 수 있으니 당황하지 않으셔도 됩니다.


원인

해당 에러가 발생한 경우 원인은 보통 Storyboard 혹은 nib에서 identifier을 지정해주지 않았거나,

identifier에 지정된 명칭이 코드와 Storyboard단에서 서로 상이해서 발생하는 문제입니다.

 

해결

해결 방법으로는 Storyboard에서 코드와 연결될 identifier을 지정해주거나 혹은 변경해주는(코드단과 동일하게 해주는)겁니다.

 

Storyboard Identifier 지정 위치 : 

Storyboard - Show the Attributes inspector 아이콘클릭 후 나오는 항목들 중 Identifier input box에서 지정

 

Storyboard에서 Identifier 지정해주기

저의 경우 TableView의 Cell을 지정할때 Storyboard와 코드단에서 사용할때의 Identifier이 서로 상이하여 찾지 못해 일어난 문제였습니다.

 

버전정보 (v1.0)

 - v1.0 2020.07.16 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Swift5] 특정 View만 화면 회전 (UINavigationController)


아까 공부하러 간다고 말씀을 드렸습니다만.. 오늘의 공부는 바로 iOS(Xcode-Swift)공부였습니다. ㅋㅋㅋ

 

iOS개발을 하다보면 가끔 특정 View에서만 화면을 회전해야하는 경우가 있습니다.

예를들어 가로->세로->가로로 하나의 화면을 세로로 보여야한다던가,

세로->가로->세로 등의 화면으로 보여줘야한다는 등 특정한 요구가 있는 경우가 있습니다.

 

그런 경우 코드로 어떻게 처리를 하는지를 알아보겠습니다.

 

특히 제가 사용하는 소스의 경우 UINavigationController가 적용된 UIViewController에서 강제적으로 화면을 회전시키는 소스입니다.

뭐, 다른 방법이 있을 수 있으나..(supportedInterfaceOrientations를 이용해 변경을 해보려했는데 잘 되지 않더군요. 저의 방법이 잘못된거일지도 모르겠지만, 대략적인 느낌은 전역으로 지정된 UINavigationController 혹은 제가 커스텀한 CustomUIViewController가 override된 supportedInterfaceOrientations를 무시하는 것 같았습니다.)

한동안 삽질을 하던 저는 이 방법을 통해 해결하였습니다.

(더 좋은 방법이 있다면 알려주시면 감사하겠습니다! 감사히 배우겠습니다!!)


 

우선 이 코드를 이해하기 위해서는 viewWillAppear 함수와 viewWillDisappear 함수에 대해 대강 이해하고 계셔야합니다.

이 함수들을 이해하기 위해서는 View Controller의 생명주기에 대해서 알고 계셔야 이해가 쉬운데요.

이 부분은 나중에 다시한번 다루도록 하겠습니다. (... 시간관계상)

 

간단히 말하면 viewWillAppear 함수와 viewWillDisappear 함수는 뷰의 생명주기에 있어 뷰가 나타날때, 뷰가 사라질때 사용(Override)하는 함수입니다. (짤막..)

네.. 지금은 뷰의 생명주기를 알려드리는 시간은 아니니 대강 그렇다는것만 이해하시면 그나마 이해하시는데 큰 문제는 없을겁니다.

 

바로 소스를 보시죠

화면을 시작할 때 회전시키기 (가로 회전 혹은 세로 회전)

override func viewWillAppear(_ animated: Bool) {

  // 화면 회전하기 (가로 회전)
  let orientation = UIInterfaceOrientation.landscapeRight.rawValue
  
  // 세로로 회전 (주석제거)
  // let orientation = UIInterfaceOrientation.portrait.rawValue

  UIDevice.current.setValue(orientation, forKey: "orientation")

  UINavigationController.attemptRotationToDeviceOrientation()

}

 

화면이 종료될 때 원상복귀시키기 (세로->가로->세로 혹은 가로->세로->가로)

override func viewWillDisappear(_ animated: Bool) {
  // 기존 세로에서 가로로 변경했었다면 다시 세로로 원상복구
  let orientation = UIInterfaceOrientation.portrait.rawValue

  // 기존 가로에서 세로로 변경했었다면 다시 가로로 원상복구 (주석제거)
  // let orientation = UIInterfaceOrientation.landscapeRight.rawValue
  
  UIDevice.current.setValue(orientation, forKey: "orientation")

  UINavigationController.attemptRotationToDeviceOrientation()

}

 

보시면 크게 어려운 건 없습니다.

세로모드 혹은 가로모드의 값을 orientation 변수에 담아서

UIDevice 클래스에 접근하여 Value, Key 형태로 저장해줍니다.

 

그리고 attemptRotationToDeviceOrientation함수에서 새로운 인터페이스 방향을 수동으로 적용해줍니다.

 

 

UIDevice - Use a UIDevice object to get information about the device such as assigned name, device model, and operating-system name and version.

대충 UIDevice 객체는 디바이스의 정보를 가져오는 용도로 사용할 수 있다는 모양입니다.

=> 그 정보로는 이름, 모델명, os 이름, 버전 등

출처 : developer.apple.com (https://developer.apple.com/documentation/uikit/uidevice)

 

Apple Developer Documentation

 

developer.apple.com

다들 아시다시피 UINavigationController 클래스도 UIViewController를 상속하여 만들어진 클래스입니다.

그러다보니 UINavgiationController만의 함수가 아닌 상속되어진 UIViewController에도 있는것으로 보입니다.

단지 제 생각이지만, 제가 supportedInterfaceOrientations 함수를 사용함에 있어서 계속해서 실패한 까닭은 이러한 상속여부에 따라 UIViewController에서는 Override가 적용이 불가하지 않았나 싶네요. (쉽게말해 무시)

 

UINavigationController.attemptRotationToDeviceOrientation - If your view controller does this, when those conditions change, your app should call this class method. The system immediately attempts to rotate to the new orientation.

대충 ViewController에서 상태의 변경이 필요한 경우 해당 메소드를 부르면 사용자가 원하는 새로운 방향으로 즉각적으로 회전을 시도한다는 모양입니다.

출처 : developer.apple.com (https://developer.apple.com/documentation/uikit/uiviewcontroller/1621400-attemptrotationtodeviceorientati)

 

Apple Developer Documentation

 

developer.apple.com


버전정보 (v1.0)

 - v1.0 2020.07.14 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Swift5] 버튼에 라운드 주기 (버튼 둥글게)


개발을 하다보면 버튼에 간단한 디자인을 입혀야하는 경우가 있습니다.

 

그중 버튼의 꼭짓점부분을 둥글게 해달라는 (라운드처리) 이야기가 간혹 있는데, 이럴때 사용하는 방법입니다.

 

기본 버튼에 라운드를 주는 방법은 쉽습니다.

UIButton.layer.cornerRadius = 8

 

일반적으로 생성한 버튼의 모습

 

아래는 소스입니다.

@IBOutlet weak var btn_info: UIButton!

override func viewDidLoad() {
	super.viewDidLoad()

	//버튼의 라운드 처리
	btn_info.layer.cornerRadius = 8

}

 

UIButton은 UIControl을 상속받으며, UIControl은 UIView를 상속받고 있습니다. (https://developer.apple.com/documentation/uikit/uibutton)

 

Apple Developer Documentation

 

developer.apple.com

특히 상속을 받는 UIView에는 멤버변수로 layer:CALayer를 가지고 있습니다. (https://developer.apple.com/documentation/uikit/uiview)

 

Apple Developer Documentation

 

developer.apple.com

이 layer변수에는 뷰에 그림을 그려줄때 필요한 핵심 애니메이션 정보를 가지고 있는데, 이 layer의 정보를 수정해줌으로 라운드 처리가 가능해지는겁니다.

 

소스를 통해 라운드가 적용된 버튼의 모습

 

위에서 설명한 layer변수를 이용하면 버튼의 색상, 타입지정, 이미지 등록 등 다양한 컨트롤이 가능한데, 이는 본 게시글의 제목의 성격이 달라지므로 다음에 설명하는 시간을 갖도록 하겠습니다.

 

 

버전정보 (v1.0)

 - v1.0 2020.07.02 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Swift5] 화면 전환하기

(storyboard와 show함수 사용)


Android에서 화면전환을 할때에는 Intent를 생성하여 startActivityForResult 함수를 사용하여 다른 액티비티로 전환을 했습니다. (Manifest도 적용을 해줘야 에러가 안난다는건 잊지말아야 하구요!)

 

하지만 iOS에서는 화면전환시 어떠한형식으로 전환을 하면 좋을까요?

사실 화면전환 방법은 다양한 방법이 있지만, 오늘은 storyboard에 id를 입력해주고, controller클래스에서 show 함수를 사용하여 화면을 전환하는 형식을 배워보도록 하겠습니다.

사실 storyboard의 경우 저는 Android의 xml에 대응한다고 생각을 하고 있습니다. (조금 다른면이 많이 있지만)

때문에 Android에서의 Intent 형식과 비슷한 형식을 취하는 방법을 알려드릴까 합니다.

 

요약해서 보기

프로젝트를 생성하시고,

Main.storyboard에서 기본생성된 ViewController에는 버튼을 생성하고(다음화면으로 이동할 이벤트 발생용),

이동할 ViewController를 추가로 생성합니다.

이동할 ViewController를 선택하시고 Identity의 Storyboard ID input 상자를 입력해줍니다.

입력된 Storyboard Id를 잘 기억하고 계시고,

초기 생성된 ViewController의 class로 이동합니다.

class에서 Button의 멤버생성 및 action이벤트를 생성합니다.

생성된 action이벤트에 아래와 같은 코드를 생성합니다.

//생성된 Main.storyboard와 연동작업 (변수에 담는 작업)
let myStoryBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
//aController에 이동할 storyBoard의 ID를 지정합니다. (다음화면의 ID)
let aController = myStoryBoard.instantiateViewController(widthIdentifier: "여기에 기억하고 계신 StoryBoard ID를 입력")
//show함수에 생성한 aController 변수를 매개변수로 넘겨줌으로써 클릭이벤트가 발생하면 이동할 storyBaord ID와 매칭되어 화면이 전환됩니다.
self.show(aController, sender: self)

 

따라해보기

0. 프로젝트를 생성하시고,

1. Main.storyboard로 이동하여 기본 생성된 ViewController와 별개로 두개의 ViewController를 생성하겠습니다.

  -> 기호에 따라 저처럼 NavigationController를 붙이셔도 됩니다!

ViewController를 추가합니다.

 

2. View를 이동하기 위한 이벤트를 걸어줄 Button을 생성합니다.

Button을 생성하고 Title를 지정합니다. (저의 경우 A Controller, B Controller라고 지었습니다.)

 

 2.1. Button에 Title을 지정하는 방법입니다.

버튼을 더블클릭해도 쉽게 변경이 가능합니다.

 - 생성된 버튼 클릭

 - 우측 상단의 Show the Attributes inspector 아이콘을 선택합니다. (선택되어있는지 확인)

 - 하단의 Title input 상자에 버튼에 보여질 Title을 입력하시면 됩니다.

 

3. 알아보기 쉽게 생성된 Controller에 각각 Label을 추가합니다.

저의 경우 A와 B로 입력했습니다. (Label의 추가 및 Title변경도 위 Button 추가하시는것처럼 진행하시면 됩니다.)

4. A를 입력한 Controller를 선택하시고,

    우측 상단의 Show the Identity Inspector 아이콘을 클릭하신 후,

    Storyboard ID input 상자를 입력해줍니다. (입력한 Storyboard ID는 잘 기억해둡니다.)

왼쪽 상자부터 클릭해가면서 차근히 따라해봅니다.

 

5. B를 입력한 Controller도 4번과 동일하게 만들어줍니다.

   단, Storyboard ID는 고유해야하므로 B는 BController등의 형식으로 입력해줍니다.

Label에 B를 입력한 Controller도 A와 동일한 작업을 해줍니다. (Storyboard ID는 다르게)

 

 -> 여기까지 Storyboard ID를 지정해 줌으로써 Android에서 xml의 android:id="@+id/~~~"와 동일한 작업을 했다고 생각하시면 되겠습니다.

 

6. 기본 생성되었던 View에 연결된 ViewController class를 storyboard와 함께 보이게 합니다.

   - 함께 보이는 방법은 우측 상단의 Add Editor on Right 버튼을 찾아 클릭하신 후, 하나는 class를 선택하시고, 하나는 storyboard를 선택하시면 됩니다.

Add Editor on Right 버튼은 이미지에 표시된 상자입니다.

7. 버튼을 우클릭한 상태로 클래스로 드래그하여 변수로 연결시켜줍니다.

여기서는 편리상 btn_a, btn_b로 생성하였습니다.

8. 7번처럼 동일한 방식으로 Action(onClick) 이벤트 함수도 생성시켜줍니다.

여기서도 편리상 onClick_a, onClick_b로 생성하였습니다.

 

9. 아래와 같이 myStoryBoard 변수의 추가와, onClick 이벤트 내 코드를 추가합니다.

여기까지 따라오셨다면 끝!

10. 실행을 해보시면 A와 B button을 누름에 따라 다른 화면(A, B)이 나옴을 확인할 수 있습니다.

 

기본 Main View
A Controller 버튼을 클릭했을때 나오는 A View

 

B Controller 버튼을 클릭했을때 나오는 B View

 

완성된 코드

class ViewController: UIViewController {


    @IBOutlet weak var btn_a: UIButton!
    @IBOutlet weak var btn_b: UIButton!
    
    //추가
    let myStoryBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    
    @IBAction func onClick_a(_ sender: Any) {
        //추가
        let aController = myStoryBoard.instantiateViewController(withIdentifier: "AController")
        
        self.show(aController, sender: self)
    }
    
    @IBAction func onClick_b(_ sender: Any) {
        //추가
        let bController = myStoryBoard.instantiateViewController(withIdentifier: "BController")
        
        self.show(bController, sender: self)
    }
    
}

 

금방 정리할 줄 알았더니 시간이 좀 걸려버렸네요.ㅠㅠㅠ

 

테스트 장비 : 맥미니(2020)

 

버전정보 (v1.0)

 - v1.0 2020.07.02 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Xcode] sotryboard에 UI Component 추가하기


솔직히 이건 아실분들은 다 아시겠지만..

Xcode 10부터는 UI Component의 위치가 달라졌습니다.

(저는 이거 몰라서 헤맸다죠 ㅋㅋㅋㅋㅋㅋ)

 

예전엔 분명 우측 하단에 존재했을 UI Component의 위치가 이제는 우측 상단 + 버튼으로 변경되었습니다.

(간만에 iOS개발하느라 바뀐걸 몰랐...)

 

- UI Componet 버튼의 위치

 -> 우측 상단 + 버튼을 찾아보세요. 아래 이미지의 파란색 상자

UI Component는 우측 상단의 + 버튼으로 변경되었습니다.

 

- UI Component 추가하는 방법

 -> 예전처럼 추가하기 원하시는 Component를 마우스로 클릭하신 상태로 드래그 해주시면 됩니다.

Label, Button 등 원하시는 Component를 클릭해서 그대로 드래그하시면 됩니다.

 

예시) Label 추가

Label을 추가한 화면

 

사실 다들 숙지하고 계시리라고는 생각하는데, 저처럼 간만에 Xcode를 만지거나, 옛날 책으로 Xcode에 입문하시는 분들이 아까운 시간을 버릴까봐 작성해봤습니다.

(이러는 저도 저거 하나 찾겠다고 진짜로 뻥아니고 몇십분 날려먹었습..)

 

테스트 장비 : 맥미니(2020)

 

버전정보 (v1.0)

 - v1.0 2020.07.01 배포

 

* 본 게시글의 이미지 및 사진의 출처는 전부 작성자 본인이 직접 제작 및 촬영하였습니다.

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com

+ Recent posts