iOSApp-Storyboard
프로젝트 2 - 기능 구현하기
프로젝트 2 - 기능 구현하기
이번시간에 기능을 구현하겠습니다.
먼저, 이 앱에서 사용할 이미지는 다음과 같습니다.
아래의 링크를 통해 다운로드해주세요.
이미지 1 다운로드 이미지 2 다운로드 이미지 3 다운로드 이미지 4 다운로드다운로드한 이미지들을 프로젝트에 넣습니다.
다음과 같이 우리가 넣은 이미지가 네비게이터에 보입니다.
자, 다음으로 Image View와 Picker View의 변수를 추가합니다.
먼저 Image View부터 추가하겠습니다.
우선 Adjust Edtitor Options를 클릭합니다. (다음 이미지의 빨간색)
그럼 다음과 같이 메뉴들이 나타납니다. Assistant를 클릭합니다.
그럼 다음과 같이 코드가 보입니다.
앞에서 기억나시나요?
변수 선언 구역, 함수 선언 구역
위의 이미지에서 viewDidLoad함수의 위는 변수 선언 구역 아래는 함수 선언 구역입니다.
그럼 Image View부터 변수를 생성합니다. 변수명은 myImages입니다.
Image View를 클릭 control을 누른 상태에서 변수 선언구역으로 끌어당깁니다.
어렵기 때문에 녹화하겠습니다.
변수명 입력 후 connect를 누릅니다.
다음과 같이 변수 선언영역에 변수가 보입니다.
같은 방법으로 Picker View의 변수도 생성합니다.
Picker View의 변수명은 myImageList입니다.
다음과 같이 Picker View의 변수도 보이네요. ^^
이제 Picker View의 기능을 적용하겠습니다.
Picker View는 조금 까다롭습니다.
여러분들은 Picker View의 함수를 이제 선언한다고 생각하셨겠지만 Picker View의 경우 함수를 직접 선언하지 않고 delegate라는 것을 사용하며 delegate가 Picker View에 대한 기능을 담당합니다.
만약 Picker View의 함수를 만들려고 시도하더라도 함수는 만들어지지 않습니다. 대신 변수가 만들어집니다.
그럼 delegate를 Picker View가 사용할 수 있게 해보겠습니다.
잘 보세요,
Main.storyboard에서 아이폰의 위에 보면 다음의 아이콘들이 보일거에요.
왼쪽에 위치한 View Controller 아이콘을 이용할거에요.
먼저, Picker View를 클릭하고 control 키를 누른 상태로 View Controller 아이콘에 갖다댑니다.
어려우니 녹화하여 보여드릴게요.
갖다대면 다음의 메뉴가 뜹니다.
delegate를 선택합니다.
화면상에 아무런 변화가 없지만 Picker View가 delegate를 사용하도록 설정했습니다.
delegate가 설정되었는지 확인하려면 Picker View를 클릭후 트랙패드를 두손가락(마우스 오른쪽 클릭)으로 누르면 다음의 정보가 나타납니다.
자 앞에서 Picker View는 delegate가 기능을 담당한다고했습니다.
그럼 delegate를 생성해서 기능을 구현합시다.
코드를 보면 클래스 ViewController가 있습니다.
그리고 옆에 보면 UIViewController가 있습니다. UIViewController도 클래스입니다.
이것은 클래스 ViewController가 UIViewController를 상속받고 있는것입니다.
우리가 delegate를 사용하기 위해서는 delegate관련한 클래스를 상속받아야합니다.
그 클래스명 UIPickerViewDelegate입니다.
그리고 Picker View에 데이터를 제공하는 UIPickerViewDataSource를 상속합니다.
여러개의 클래스를 상속받으려면 ,로 구분하여 작성합니다.
코드를 다음과 같이 수정합니다.
수정 전
class ViewController: UIViewController {
수정 후
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
이렇게 작성하다보면 다음과 같이 경고표시가 나타납니다.
이 때 빨간색 원을 클릭하면 다음과 같이 표시됩니다.
위의 이미지에서 하단 우측에 보이는 Fix를 누릅니다.
그럼, 다음과 같이 2개의 함수가 추가됩니다. 이 두 함수는 Picker View와 관련한 일을 담당하므로 필요한 함수입니다.
numberOfComponents함수는 PickerView가 표시하는 열의 개수를 반환하는 작업합니다.
우리가 사용하는 Picker View의 열의 수는 1개입니다.
이 함수가 스스로 마법처럼 1개를 알아서 반환하는건 아니고 우리가 반환할 개수를 작성해줘야합니다.
참고로 열의 수는 1개 아니면 2개 3개 4개 이런식이므로 반드시 정수를 반환합니다.
다음과 같이 함수내에서 직접 수 작성해서 반환해도 좋습니다.
func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 }
또는 변수나 상수를 선언하여 해당 변수에 값을 대입 후 해당 변수를 반환해도 좋습니다.
다음과 같이요.
let NUMBER_OF_PICKERVIEW_COLUMN = 1 func numberOfComponents(in pickerView: UIPickerView) -> Int { return NUMBER_OF_PICKERVIEW_COLUMN }
저는 상수를 선언하여 위와 같이 작성하겠습니다. 혼란을 막기위해 따라해주세요.
그럼 현재까지의 최종코드는 다음과 같습니다.
import UIKit class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { let NUMBER_OF_PICKERVIEW_COLUMN = 1 func numberOfComponents(in pickerView: UIPickerView) -> Int { return NUMBER_OF_PICKERVIEW_COLUMN } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { } @IBOutlet var myImages: UIImageView! @IBOutlet var myImageList: UIPickerView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } }
numberOfRowsInComponent 함수는 Picker View에서 사용할 데이터의 개수를 지정합니다.
이것 또한 정수로 반환해야하며 상수나 변수를 선언해서 사용해도 괜찮고 직접 개수를 지정해도 괜찮습니다.
우리가 사용할 이미지들은 총 5개입니다.
파일명은 다음과 같지요.
project2-img.png
project2-img2.png
project2-img3.png
project2-img4.png
happyCatHeader.png
사용할 코드는 다음과 같습니다.
이 파일 목록을 배열로 만들어서 배열의 수를 반환하겠습니다.
var myImageArr = [ "project2-img.png","project2-img2.png","project2-img3.png","project2-img4.png","happyCatHeader.png" ] func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return myImageArr.count }
그러면 최종코드는 다음과 같습니다.
import UIKit class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { let NUMBER_OF_PICKERVIEW_COLUMN = 1 var myImageArr = [ "project2-img.png","project2-img2.png","project2-img3.png","project2-img4.png","happyCatHeader.png" ] func numberOfComponents(in pickerView: UIPickerView) -> Int { return NUMBER_OF_PICKERVIEW_COLUMN } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return myImageArr.count } @IBOutlet var myImages: UIImageView! @IBOutlet var myImageList: UIPickerView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } }
그리고 만들어야할 delegate 관련한 함수가 하나 더 있습니다. Picker View에 표시할 아이템을 반환하는 함수입니다.
다음의 코드를 작성합니다.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return myImageArr[row] }
앞에서 생성한 배열을 사용했으며 배열의 목록을 반환합니다.
여기까지 작성한 최종코드는 다음과 같습니다.
import UIKit class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { let NUMBER_OF_PICKERVIEW_COLUMN = 1 var myImageArr = [ "project2-img.png","project2-img2.png","project2-img3.png","project2-img4.png","happyCatHeader.png" ] func numberOfComponents(in pickerView: UIPickerView) -> Int { return NUMBER_OF_PICKERVIEW_COLUMN } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return myImageArr.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return myImageArr[row] } @IBOutlet var myImages: UIImageView! @IBOutlet var myImageList: UIPickerView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } }
그럼 시뮬레이터를 작동해봅시다.
하단에 PickerView를 보니 우리가 사용할 이미지 파일의 목록이 잘 나타납니다.
Image View영역에서 이미지가 안나오시는 분은 신경안쓰셔도 괜찮습니다.
이제 우리가 선택한 이미지가 나오게 할거니까요. ^^
이제 Picker View에서 아이템이 선택되면 해당 이미지가 나타나도록 해보겠습니다.
굿굿!!
이를 가능하게 하기위해 delegate함수를 하나 더 추가합니다.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { }
이 didSelectRow 함수는 Picker View에서 아이템이 선택되면 작동합니다.
우리가 앞에서 label에 text를 대입하는 방법이 기억나시나요?
변수명.text = "텍스트"
이미지는 위와 같이 단순하지 않습니다.
이번에는 Image View에 image를 대입해야합니다.
아래와 같은 방법으로 가능하지 않습니다.
이미지뷰변수명.image = 이미지파일명
파일명을 UIImage타입으로 변수로 생성해야합니다.
파일명을 UIImage타입으로 변수로 생성하는 방법은 다음과 같습니다.
let 상수명 = UIImage(named: 파일명)
자 그럼 해봅시다.
ViewController 클래스에서 앱이 실행 된 후 실행할 명령문은 viewDidLoad()함수에서 처리합니다.
그러면 Image View에서 처음으로 표시할 이미지를 설정해봅시다.
방법은 위에서 설명한대로입니다.. 즉 코드는 다음과 같지요.
ImageView변수.image = UIImage타입 변수
자 그럼 project2-img2.png 파일이 앱을 켜면 처음 나오는 이미지로 해봅시다.
먼저 UIImage변수 선언합니다.
let firstAppImage = UIImage(named: "project2-img2.png")
위에서 UIImage타입의 상수를 선언했습니다.
그럼 이번에는 Image View에 넣겠습니다.
Image View의 변수명은 myImages입니다. 그러므로 코드는 다음과 같습니다.
myImages.image = firstAppImage
그럼 다음의 코드를 viewDidLoad()함수에 넣어보시기 바랍니다.
let firstAppImage = UIImage(named: "project2-img2.png") myImages.image = firstAppImage
그럼 viewDidLoad함수는 다음과 같습니다.
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. let firstAppImage = UIImage(named: "project2-img2.png") myImages.image = firstAppImage }
현재까지의 전체 코드는 다음과 같습니다.
그럼 시뮬레이터를 켜서 다음의 이미지가 잘 나오나 봅시다.
다음과 같이 초기 이미지가 잘 나옵니다.
이렇게 Image View 라이브러리에 이미지 설정하는 방법을 알아봤습니다.
그럼 이제 우리가 원하는 작업을 해봅시다.
먼저 이미지 파일명 자체를 사용못하는 것을 알았기 때문에 이미지 파일명을 UIImage타입으로 선언해 배열에 담겠습니다.
이미지를 담을 때는 배열도 UIImage타입으로 생성해야합니다.
UIImage타입으로 배열을 선언하는 방법은 다음의 코드입니다.
var showMyImageArr = [UIImage?]();
위의 코드를 변수 myImageArr 아래에 입력해 주세요.
그럼 이렇게 됩니다.
UIImage타입의 변수를 담을 배열을 생성했습니다. 이제 그 배열에 UIImage타입의 변수를 넣어줍니다.
이 작업은 앱이 실행된 후 작업하므로 viewDidLoad함수에서 처리합니다.
반복문 중 하나인 for문을 사용하겠습니다.
for i in 0 ..< myImageArr.count { let myUIImage = UIImage(named: myImageArr[i]) showMyImageArr.append(myUIImage) }
for i in 0 ..< myImageArr.count { 는 index 0 부터 myImageArr배열의 개수인 5미만까지 반복하는 for문입니다.
let myUIImage = UIImage(named: myImageArr[i]) 는 myImageArr 배열에 파일명이 텍스트로 있기때문에 하나씩 myImageArr[i]를 사용해 UIImage타입으로 선언합니다.
showMyImageArr.append(myUIImage)는 배열에 값을 추가하려면 append()함수를 사용합니다.
자, 그럼 viewDidLoad에 위의 코드를 추가합니다.
그러면 위의 viewDidLoad함수는 다음과 같습니다.
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. for i in 0 ..< myImageArr.count { let myUIImage = UIImage(named: myImageArr[i]) showMyImageArr.append(myUIImage) } let firstAppImage = UIImage(named: "project2-img2.png") myImages.image = firstAppImage }
우리는 UIImage타입으로 배열을 생성했습니다. 그 배열은 showMyImageArr 이지요. 그럼 delegate의 didSelectRow 함수에 선택한 Pick View의 아이템에 따라 Image View의 값을 변경해봅시다.
Image View의 변수는 myImages입니다. 그러므로 showMyImageArr배열의 값을 대입하면
myImages.image = showMyImageArr[인덱스]
didSelectRow안에서 사용하는 인덱스 변수명은 row입니다. 그러므로
myImages.image = showMyImageArr[row]
위의 코드를 didSelectRow안에 넣습니다. 그럼 didSelectRow는 다음과 같습니다.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { myImages.image = showMyImageArr[row] }
여기까지 하면 최종코드는 다음과 같습니다.
import UIKit class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { let NUMBER_OF_PICKERVIEW_COLUMN = 1 var myImageArr = [ "project2-img.png","project2-img2.png","project2-img3.png","project2-img4.png","happyCatHeader.png" ] var showMyImageArr = [UIImage?](); func numberOfComponents(in pickerView: UIPickerView) -> Int { return NUMBER_OF_PICKERVIEW_COLUMN } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return myImageArr.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return myImageArr[row] } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { myImages.image = showMyImageArr[row] } @IBOutlet var myImages: UIImageView! @IBOutlet var myImageList: UIPickerView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. for i in 0 ..< myImageArr.count { let myUIImage = UIImage(named: myImageArr[i]) showMyImageArr.append(myUIImage) } let firstAppImage = UIImage(named: "project2-img2.png") myImages.image = firstAppImage } }
조금은 이상하지만 아이템을 선택할 때마다 이미지가 변경됩니다.
이상한 점은 우리가 초기 이미지를 project2-img2.png로 설정했기 때문입니다.
그래서 가장 처음에 나와야 하는 이미지는 project2-img.png로 해야합니다.
그럼 코드를 수정하겠습니다.
수정할 코드
let firstAppImage = UIImage(named: "project2-img2.png")
수정 후
let firstAppImage = UIImage(named: "project2-img.png")
다시 실행해봅시다.
이번엔 완벽하게 작동합니다.
하지만 이미지 파일명을 담은 배열의 순서가 변경된 경우에도 project2-img.png 파일이 가장 먼저 노출되므로 좋지 않습니다. 다음과 같이 배열의 가장 첫번째 값으로 변경합니다.
let firstAppImage = UIImage(named: myImageArr[0])
여기까지의 최종코드는 다음과 같습니다.
import UIKit class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { let NUMBER_OF_PICKERVIEW_COLUMN = 1 var myImageArr = [ "project2-img.png","project2-img2.png","project2-img3.png","project2-img4.png","happyCatHeader.png" ] var showMyImageArr = [UIImage?](); func numberOfComponents(in pickerView: UIPickerView) -> Int { return NUMBER_OF_PICKERVIEW_COLUMN } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return myImageArr.count } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return myImageArr[row] } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { myImages.image = showMyImageArr[row] } @IBOutlet var myImages: UIImageView! @IBOutlet var myImageList: UIPickerView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. for i in 0 ..< myImageArr.count { let myUIImage = UIImage(named: myImageArr[i]) showMyImageArr.append(myUIImage) } let firstAppImage = UIImage(named: myImageArr[0]) myImages.image = firstAppImage } }
그럼 실행해 보시기바랍니다. ^^
저는 잘 작동합니다. ^^
//=$langList['bottomThankyou'][$langMode]?>