꾸준히 안타치기
① Picker View - userDefault 본문
반응형
피커뷰 구현하기 ( 계정 텍스트뷰를 누르면 화면하단에 피커뷰 등장 )
- 피커뷰는 셀렉트나 콤보박스 등의 기능을 하는 입력용뷰이다. 이미지피커뷰와는 전혀연관이 없다.
- 피켜뷰와 테이블뷰는 유사하다. 차이점은 테이블뷰는 UITableViewCell객체를 생성해야하는것 외에 유사함.
- 피커뷰는 문자열을 아이템으로 갖는 배열 타입의 데이터 소스를 사용한다.
메인스토리보드를 열고 테이블뷰추가 +네비게이션 컨트롤러 임베디드한다.
테이블뷰 셀을 정적으로 변경
테이블뷰 셀 추가
아래와 같이 화면구성하기
ListViewController.swift파일 생성후, 스토리보드의 테이블뷰 클래스와 연결한다.
아울렛액션으로 텍스트필드, 이름, 세그먼트컨트롤을 ,스위치버튼을 연결한다.
ViewDidLoad메소드를 추가하고, 메소드 내부에서 피커뷰 인스턴스를 생성한다.
델리게이트 객체를 지정하고, 텍스트필드의 입력방식을 가상키보드 대신 피커뷰로 설정한다.
import UIKit
class ListViewController :UITableViewController ,UIPickerViewDelegate,UIPickerViewDataSource{
@IBOutlet weak var account: UITextField!
// 계정목록을 담을 배열
var accountlist = [String]()
@IBOutlet weak var name: UILabel!
@IBOutlet weak var gender: UISegmentedControl!
@IBOutlet weak var married: UISwitch!
//피커뷰
override func viewDidLoad() {
let picker = UIPickerView()
//피커뷰의 델리게이트 객체 지정
picker.delegate = self
//account 텍스트필드 입력 방식을 가상 키보드 대신 피커뷰로 설정
self.account.inputView = picker
}
계정 목록을 담을 배열을 작성한다.
// 계정목록을 담을 배열정의
var accountlist = [String]()
구현해야할 델리게이트 메소드는 모두 4개이다. ( 테이블뷰와 유사)
//생성할 컴포턴트의 갯수를 정의합니다.
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
//지정된 컴포턴트가 가질 목록의 길이를 정의합니다.
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
// 위에 정의한 계정목록 내역을 수만큼 가져온다.
return self.accountlist.count
}
// 지정된 컴포넌트의 목록 각 행에 출력될 내용을 정의합니다.행번호에 맞게출력된다.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.accountlist[row]
}
// 지정된 컴포넌트의 목록 각 행을 사용자가 선택했을 때 실행할 액션을 정의합니다.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// 선택된 계정값을 텍스트 필드에 입력
let account = self.accountlist[row]
self.account.text = account
// 입력 뷰를 닫음
// self.view.endEditing(true)
}
피커뷰에 Done버튼 추가하기
//피커뷰
override func viewDidLoad() {
let picker = UIPickerView()
//피커뷰의 델리게이트 객체 지정
picker.delegate = self
//account 텍스트필드 입력 방식을 가상 키보드 대신 피커뷰로 설정
self.account.inputView = picker
//툴바 객체 정의
let toolbar = UIToolbar()
toolbar.frame = CGRect(x: 0, y: 0, width: 0, height: 35)
toolbar.barTintColor = .lightGray
//액세서리 뷰 영역에 툴바를 표시
self.account.inputAccessoryView = toolbar
//툴바에 들어갈 닫기 버튼
let done = UIBarButtonItem()
done.title = "Done"
done.target = self
done.action = #selector(pickerDone)// 화면닫기메소드
툴바에 버튼을 추가하려면, 인터페이스 빌더가 아니라 프로그래밍 방식으로 툴 바를 추가해야한다.
툴바를 프로그래밍 방식으로 생성할 때에는 높이만 설정해주면 된다.
툴바의 아템 배치를 위해 두개의 특수타입 버튼을 제공한다.
-Fixed Space Bar Button Item ( 왼쪽 여백 )
-Flexible Space Bar Button Item ( 빈공간 채우기, 자신이 들어가야할 폭 스스로 계산해 자동조절 )
피커뷰에 New버튼 추가하고, 툴바에 New / 사이공간/ Done버튼 순으로 추가한다.
//신규계정등록버튼
let new = UIBarButtonItem()
new.title = "New"
new.target = self
new.action = #selector(newAccount(_:))// 계정추가팝업메소드
// 가변 폭 버튼 정의
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
//버튼을 모두 툴바에 추가 뉴버튼 / 사이공간 / 닫기버튼
toolbar.setItems([new,flexSpace,done], animated: true)
}
버튼을 눌렀을때의 액션을 정의한다.
// 피커뷰 닫기버튼
@objc func pickerDone(_ sender: Any){
self.view.endEditing(true)
}
// 게정추가버튼
@objc func newAccount(_ sender: Any){
// 일단 열려있는 입력용 뷰부터 닫아준다.
self.view.endEditing(true)
//알림창 객체 생성
let alert = UIAlertController(title: "새 계정을 입력하세요", message: nil, preferredStyle: .alert)
//입력폼 추가
alert.addTextField(){
$0.placeholder = "ex) abc@gmail.com"
}
//버튼 및 액션 정의
alert.addAction(UIAlertAction(title: "OK", style: .default){ (_) in
if let account = alert.textFields?[0].text {
//계정 목록 배열에 추가한다.
self.accountlist.append(account)
//계정 텍스트 필드에 표시한다.
self.account.text = account
}
})
//알림창 오픈
self.present(alert, animated: false, completion: nil)
}
(계정 텍스트뷰 누르고 -> 피커뷰 열림, 닫기버튼, 계정추가까지 - 전체코드)
import UIKit
class ListViewController :UITableViewController ,UIPickerViewDelegate,UIPickerViewDataSource{
@IBOutlet weak var account: UITextField!
// 계정목록을 담을 배열정의
var accountlist = [String]()
@IBOutlet weak var name: UILabel!
@IBOutlet weak var gender: UISegmentedControl!
@IBOutlet weak var married: UISwitch!
//피커뷰
override func viewDidLoad() {
let picker = UIPickerView()
//피커뷰의 델리게이트 객체 지정
picker.delegate = self
//account 텍스트필드 입력 방식을 가상 키보드 대신 피커뷰로 설정
self.account.inputView = picker
//툴바 객체 정의
let toolbar = UIToolbar()
toolbar.frame = CGRect(x: 0, y: 0, width: 0, height: 35)
toolbar.barTintColor = .lightGray
//액세서리 뷰 영역에 툴바를 표시
self.account.inputAccessoryView = toolbar
//툴바에 들어갈 닫기 버튼
let done = UIBarButtonItem()
done.title = "Done"
done.target = self
done.action = #selector(pickerDone)// 닫기메소드
//신규계정등록버튼
let new = UIBarButtonItem()
new.title = "New"
new.target = self
new.action = #selector(newAccount(_:))// 계정추가메소드
// 가변 폭 버튼 정의
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
//버튼을 모두 툴바에 추가 뉴버튼 / 사이공간 / 닫기버튼
toolbar.setItems([new,flexSpace,done], animated: true)
}
//생성할 컴포턴트의 갯수를 정의합니다.
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
//지정된 컴포턴트가 가질 목록의 길이를 정의합니다.
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.accountlist.count
}
// 지정된 컴포넌트의 목록 각 행에 출력될 내용을 정의합니다.행번호에 맞게출력된다.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.accountlist[row]
}
// 지정된 컴포넌트의 목록 각 행을 사용자가 선택했을 때 실행할 액션을 정의합니다.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// 선택된 계정값을 텍스트 필드에 입력
let account = self.accountlist[row]
self.account.text = account
// 입력 뷰를 닫음
// self.view.endEditing(true)
}
// 피커뷰 닫기버튼
@objc func pickerDone(_ sender: Any){
self.view.endEditing(true)
}
// 게정추가버튼
@objc func newAccount(_ sender: Any){
// 일단 열려있는 입력용 뷰부터 닫아준다.
self.view.endEditing(true)
//알림창 객체 생성
let alert = UIAlertController(title: "새 계정을 입력하세요", message: nil, preferredStyle: .alert)
//입력폼 추가
alert.addTextField(){
$0.placeholder = "ex) abc@gmail.com"
}
//버튼 및 액션 정의
alert.addAction(UIAlertAction(title: "OK", style: .default){ (_) in
if let account = alert.textFields?[0].text {
//계정 목록 배열에 추가한다.
self.accountlist.append(account)
//계정 텍스트 필드에 표시한다.
self.account.text = account
}
})
//알림창 오픈
self.present(alert, animated: false, completion: nil)
}
}
이름 결혼여부 성별 추가
//피커뷰
override func viewDidLoad() {
//기본 저장소 객체 불러오기
let plist = UserDefaults.standard
//불러온 값을 설정
self.name.text = plist.string(forKey: "name")//이름
self.married.isOn = plist.bool(forKey: "married")//성별
self.gender.selectedSegmentIndex = plist.integer(forKey: "gender")//결혼여부
}
성별 액션메소드 - 세그먼트컨트롤
// 성별액션메소드
@IBAction func changeGender(_ sender: UISegmentedControl) {
let value = sender.selectedSegmentIndex //0이면 남자, 1이면 여자
let plist = UserDefaults.standard // 기본객체저장소를 가져옴
plist.set(value, forKey: "gender")//젠더라는키로 가져옴
plist.synchronize()// 동기화
}
결혼여부 스위치 액션메소드
// 결혼여부액션메소드
@IBAction func changeMarried(_ sender: UISwitch) {
let value = sender.isOn //트루면 기혼
let plist = UserDefaults.standard
plist.set(value, forKey: "married")
plist.synchronize()
}
이름 클릭시 알림창을 띄우기 위해 테이블뷰에 대한 델리게이트 메소드 추가
//테이블뷰에 대한 델리게이트 메소드를 추가.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 1 { //두번째 셀이 클릭되었을때
//입력이 가능한 알림창을 띄워 이름을 수정할수 있게한다.
let alert = UIAlertController(title: nil, message: "이름을 입력하세요", preferredStyle: .alert)
//입력필드 추가
alert.addTextField(){
$0.text = self.name.text // 이름레이블의 텍스트 넣어주기
}
// 버튼 및 액션 추가
alert.addAction(UIAlertAction(title: "OK", style: .default){(_) in
//사용자가 OK버튼을 누르면 입력 필드에 입력된 값을 저장한다.
let value = alert.textFields?[0].text
let plist = UserDefaults.standard
plist.setValue(value,forKey: "name")
plist.synchronize()
self.name.text = value
})
//알림창띄움
self.present(alert, animated: false, completion: nil)
}
}
피커뷰안의 계정 추가 버튼액션 메소드에 내용추가
// 게정추가버튼
@objc func newAccount(_ sender: Any){
// 일단 열려있는 입력용 뷰부터 닫아준다.
self.view.endEditing(true)
//알림창 객체 생성
let alert = UIAlertController(title: "새 계정을 입력하세요", message: nil, preferredStyle: .alert)
//입력폼 추가
alert.addTextField(){
$0.placeholder = "ex) abc@gmail.com"
}
//버튼 및 액션 정의
alert.addAction(UIAlertAction(title: "OK", style: .default){ (_) in
if let account = alert.textFields?[0].text {
//계정 목록 배열에 추가한다.
self.accountlist.append(account)
//계정 텍스트 필드에 표시한다.
self.account.text = account
//컨트롤 값을 모두 초기화한다.**************************** 추가부분 ********
self.name.text = ""
self.gender.selectedSegmentIndex = 0
self.married.isOn = false
//*****************************************************************
}
})
//알림창 오픈
self.present(alert, animated: false, completion: nil)
}
신규계정이 등록되면 이름, 성별, 결혼여부객체의 값을 모두 초기화해준다.
데이터의 저장을 위해서는 가장먼저 마스터 데이터를 구성해야한다. 마스터데이터란? 병렬적으로 분산된 데이터들을 찾기 위한 단초가 되는 목록형태의 가장 기본적인 데이터를 의미한다. 기초데이터라는 의미로 시드데이터라고도 한다.
추가한 계정목록을 통째로 저장해보자.
newAccount메소드에 아래 구문을 추가한다.
// 계정 목록을 통째로 저장한다.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
let plist = UserDefaults.standard
plist.set(self.accountlist, forKey: "accountlist")
// 신규로 등록시 계정값을 받아서 selectedAccount키로 저장한다.
plist.set(account, forKey: "selectedAccount")
plist.synchronize()
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
더보기
// 게정추가버튼
@objc func newAccount(_ sender: Any){
// 일단 열려있는 입력용 뷰부터 닫아준다.
self.view.endEditing(true)
//알림창 객체 생성
let alert = UIAlertController(title: "새 계정을 입력하세요", message: nil, preferredStyle: .alert)
//입력폼 추가
alert.addTextField(){
$0.placeholder = "ex) abc@gmail.com"
}
//버튼 및 액션 정의
alert.addAction(UIAlertAction(title: "OK", style: .default){ (_) in
if let account = alert.textFields?[0].text {
//계정 목록 배열에 추가한다.
self.accountlist.append(account)
//계정 텍스트 필드에 표시한다.
self.account.text = account
//컨트롤 값을 모두 초기화한다.
self.name.text = ""
self.gender.selectedSegmentIndex = 0
self.married.isOn = false
// 계정 목록을 통째로 저장한다.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
let plist = UserDefaults.standard
plist.set(self.accountlist, forKey: "accountlist")
// 신규로 등록시 계정값을 받아서 selectedAccount키로 저장한다.
plist.set(account, forKey: "selectedAccount")
plist.synchronize()
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}
})
//알림창 오픈
self.present(alert, animated: false, completion: nil)
}
선택한 계정정보 저장하기 @@@@@@부분추가
사용자가 피커뷰를 통해 계정을 변경할 때마다 또는 사용자가 신규 계정을 등록했을때 저장이되어야한다.
계정을 등록함과 동시에 계정이 선택이된다.
// 지정된 컴포넌트의 목록 각 행을 사용자가 선택했을 때 실행할 액션을 정의합니다.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// 선택된 계정값을 텍스트 필드에 입력
let account = self.accountlist[row]
self.account.text = account
//사용자가 계정을 생성하면 이 계정을 선택한 것을 간주하고 저장한다.@@@@@@@@@@@@@@@@@@@@@@@@@
// 피커뷰를 통해 계정을 변경할때마다 저장
let plist = UserDefaults.standard
plist.set(account, forKey: "selectedAccount")
plist.synchronize()
// 입력 뷰를 닫음
// self.view.endEditing(true)
}
newAccount(_ sender: Any)에 추가 신규계정 등록시 selectedAccount키로 저장
plist.set(account, forKey: "selectedAccount")
viewDidLoad메소드에 다음구문 추가
// 계정정보 읽어오기 /////////////////////////////////////////////////////////////////////////////
// accountlist키 로 저장된 값을 읽어온다. 저장된 값이 없을 경우 새로운 배열객체를 생성한다.
let accountlist = plist.array(forKey: "accountlist") as? [String] ?? [String]()
// 읽어온값을 멤버변수에 대입한다.
self.accountlist = accountlist
// selectedAccount키로 저장된 값을 읽어온다.
if let account = plist.string(forKey: "selectedAccount"){
// 값이 있을경우에 account의 텍스트 필드 값으로 대입한다.
self.account.text = account
전체코드
import UIKit
class ListViewController :UITableViewController ,UIPickerViewDelegate,UIPickerViewDataSource{
@IBOutlet weak var account: UITextField!
// 계정목록을 담을 배열정의
var accountlist = [String]()
@IBOutlet weak var name: UILabel! // 이름
@IBOutlet weak var gender: UISegmentedControl!//성별
@IBOutlet weak var married: UISwitch!//결혼여부
//피커뷰
override func viewDidLoad() {
//기본 저장소 객체 불러오기
let plist = UserDefaults.standard
//불러온 값을 설정
self.name.text = plist.string(forKey: "name")//이름
self.married.isOn = plist.bool(forKey: "married")//성별
self.gender.selectedSegmentIndex = plist.integer(forKey: "gender")//결혼여부
let picker = UIPickerView()
//피커뷰의 델리게이트 객체 지정
picker.delegate = self
//account 텍스트필드 입력 방식을 가상 키보드 대신 피커뷰로 설정
self.account.inputView = picker
//툴바 객체 정의
let toolbar = UIToolbar()
toolbar.frame = CGRect(x: 0, y: 0, width: 0, height: 35)
toolbar.barTintColor = .lightGray
//액세서리 뷰 영역에 툴바를 표시
self.account.inputAccessoryView = toolbar
//툴바에 들어갈 닫기 버튼
let done = UIBarButtonItem()
done.title = "Done"
done.target = self
done.action = #selector(pickerDone)// 닫기메소드
//신규계정등록버튼
let new = UIBarButtonItem()
new.title = "New"
new.target = self
new.action = #selector(newAccount(_:))// 계정추가메소드
// 가변 폭 버튼 정의
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
//버튼을 모두 툴바에 추가 뉴버튼 / 사이공간 / 닫기버튼
toolbar.setItems([new,flexSpace,done], animated: true)
// 계정정보 읽어오기 /////////////////////////////////////////////////////////////////////////////
// accountlist키 로 저장된 값을 읽어온다. 저장된 값이 없을 경우 새로운 배열객체를 생성한다.
let accountlist = plist.array(forKey: "accountlist") as? [String] ?? [String]()
// 읽어온값을 멤버변수에 대입한다.
self.accountlist = accountlist
// selectedAccount키로 저장된 값을 읽어온다.
if let account = plist.string(forKey: "selectedAccount"){
// 값이 있을경우에 account의 텍스트 필드 값으로 대입한다.
self.account.text = account
}
}
//생성할 컴포턴트의 갯수를 정의합니다.
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
//지정된 컴포턴트가 가질 목록의 길이를 정의합니다.
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.accountlist.count
}
// 지정된 컴포넌트의 목록 각 행에 출력될 내용을 정의합니다.행번호에 맞게출력된다.
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.accountlist[row]
}
// 지정된 컴포넌트의 목록 각 행을 사용자가 선택했을 때 실행할 액션을 정의합니다.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// 선택된 계정값을 텍스트 필드에 입력
let account = self.accountlist[row]
self.account.text = account
//사용자가 계정을 생성하면 이 계정을 선택한 것을 간주하고 저장한다.@@@@@@@@@@@@@@@@@@@@@@@@@
let plist = UserDefaults.standard
plist.set(account, forKey: "selectedAccount")
plist.synchronize()
// 입력 뷰를 닫음
// self.view.endEditing(true)
}
// 피커뷰 닫기버튼
@objc func pickerDone(_ sender: Any){
self.view.endEditing(true)
}
// 게정추가버튼
@objc func newAccount(_ sender: Any){
// 일단 열려있는 입력용 뷰부터 닫아준다.
self.view.endEditing(true)
//알림창 객체 생성
let alert = UIAlertController(title: "새 계정을 입력하세요", message: nil, preferredStyle: .alert)
//입력폼 추가
alert.addTextField(){
$0.placeholder = "ex) abc@gmail.com"
}
//버튼 및 액션 정의
alert.addAction(UIAlertAction(title: "OK", style: .default){ (_) in
if let account = alert.textFields?[0].text {
//계정 목록 배열에 추가한다.
self.accountlist.append(account)
//계정 텍스트 필드에 표시한다.
self.account.text = account
//컨트롤 값을 모두 초기화한다.
self.name.text = ""
self.gender.selectedSegmentIndex = 0
self.married.isOn = false
// 계정 목록을 통째로 저장한다.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
let plist = UserDefaults.standard
plist.set(self.accountlist, forKey: "accountlist")
// 신규로 등록시 계정값을 받아서 selectedAccount키로 저장한다.
plist.set(account, forKey: "selectedAccount")
plist.synchronize()
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}
})
//알림창 오픈
self.present(alert, animated: false, completion: nil)
}
// 성별액션메소드
@IBAction func changeGender(_ sender: UISegmentedControl) {
let value = sender.selectedSegmentIndex //0이면 남자, 1이면 여자
let plist = UserDefaults.standard // 기본객체저장소를 가져옴
plist.set(value, forKey: "gender")//젠더라는키로 가져옴
plist.synchronize()// 동기화
}
// 결혼여부액션메소드
@IBAction func changeMarried(_ sender: UISwitch) {
let value = sender.isOn //트루면 기혼
let plist = UserDefaults.standard
plist.set(value, forKey: "married")
plist.synchronize()
}
//테이블뷰에 대한 델리게이트 메소드를 추가.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 1 { //두번째 셀이 클릭되었을때
//입력이 가능한 알림창을 띄워 이름을 수정할수 있게한다.
let alert = UIAlertController(title: nil, message: "이름을 입력하세요", preferredStyle: .alert)
//입력필드 추가
alert.addTextField(){
$0.text = self.name.text // 이름레이블의 텍스트 넣어주기
}
// 버튼 및 액션 추가
alert.addAction(UIAlertAction(title: "OK", style: .default){(_) in
//사용자가 OK버튼을 누르면 입력 필드에 입력된 값을 저장한다.
let value = alert.textFields?[0].text
let plist = UserDefaults.standard
plist.setValue(value,forKey: "name")
plist.synchronize()
self.name.text = value
})
//알림창띄움
self.present(alert, animated: false, completion: nil)
}
}
}
반응형
'iOS > 기본편 | 실전편 -꼼꼼한재은씨' 카테고리의 다른 글
SideBar / 라이브러리 사용X (0) | 2022.02.15 |
---|---|
② Picker View - customPlist / 커스텀 (0) | 2022.02.12 |
UserDefaults (0) | 2022.02.10 |
SideBar / SWRevealViewController 라이브러리 사용 (0) | 2022.02.09 |
메모장 만들기(스토리보드) +배경이미지 + 얼럿창이미지추가 (0) | 2022.02.06 |
Comments