일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Swift flutterviewcontroller
- 스위프트 앨범
- 스위프트 푸시
- silent push
- 앱 꺼졌을 때 푸시 데이터 저장
- 스위프트 웹뷰
- 앱 백그라운드 푸시 데이터 저장
- 스위프트 UserDefaults
- swift sms
- 안드로이드 FCM
- 플러터 뷰 컨트롤러
- 안드로이드 바로가기
- flutter rotate
- 노티피케이션 익스텐션
- NotificationService Extension
- 푸시 데이터 저장
- Swift flutterview
- 안드로이드 에러
- swift 문자
- swift autolayout
- 스위프트
- 스위프트 카메라
- native flutter view
- 안드로이드 숏컷
- Flutter UIKitView MethodChannel
- flutter 회전
- FlutterView MethodChannel
- Flutter NativeView
- 스위프트 테이블 뷰 셀
- 안드로이드 앨범
- Today
- Total
Things take time
[SWIFT] 2일차 : 스위프트 기본 앱 본문
[SWIFT]
- 교재 : 스위프트로 아이폰 앱 만들기 입문
1. ID/PW 입력 및 경고창 출력
import UIKit class ViewController: UIViewController { @IBOutlet var txtID: UITextField! @IBOutlet var txtPW: UITextField! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func btnSend(_ sender: UIButton) { let alert = UIAlertController(title: "Do it Swift", message: txtID.text! + " " + txtPW.text!, preferredStyle: .alert) // 클로저 함수 & Function (파라미터) -> 리턴형 in ... alert.addAction(UIAlertAction(title: "OK", style: .default, handler: {(action: UIAlertAction) -> Void in print("OK 버튼 클릭") })) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: {(action: UIAlertAction) -> Void in print("Cancel 버튼 클릭") })) alert.addAction(UIAlertAction(title: "Another", style: .default, handler: {(action: UIAlertAction) -> Void in print("Another") })) self.present(alert, animated: true) { () -> Void in print("메시지 박스 출력") } } }
- 각 컴포넌트의 Attributes inspector는 설정을 정의할 수 있음
- 비밀번호 텍스트 필드의 경우 하단의 Secure Text Entry를 설정하고, 자동 완성과 같은 기능을 제거하려면 Correction을 No로 설정
- UIAlertView 클래스를 사용하여 경고 창을 만들 수 있으나, deprecated 함수이므로 UIAlertController를 사용하길 권장
- 경고창 버튼 2개 생성 시 좌, 우로 배치되나 그 초과된 개수에 대해서는 세로로 배치 됨
2. 이미지 뷰, 축소 확대 버튼, 스위치
import UIKit class ViewController: UIViewController { var isZoom: Bool = false var imgOn: UIImage? var imgOff: UIImage? let zoomScale: CGFloat = 2.0 @IBOutlet var imgView: UIImageView! override func viewDidLoad() { super.viewDidLoad() // named 뒤에 주소를 상대적으로 받는 이유는 이미지 추가 시, 이미지가 소스폴더와 같은 위치에 있을s 경우 imgOn = UIImage(named: "lamp_on.png") imgOff = UIImage(named: "lamp_off.png") // imgView는 UIImageView 클래스 변수이며, UIImageView 클래스내에 image라는 변수가 이미지를 가리키는 객체임 imgView.image = imgOff } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func btnResizeImage(_ sender: UIButton) { if sender.currentTitle == "확대"{ // imgView.frame.size = CGSize(width: zoomScale, height: zoomScale) imgView.frame.size.width *= zoomScale imgView.frame.size.height *= zoomScale // for : state sender.setTitle("축소", for: .normal) }else if sender.currentTitle == "축소"{ imgView.frame.size.width /= zoomScale imgView.frame.size.height /= zoomScale sender.setTitle("확대", for: .normal) } } // 액션 연결시, UISwitch로 연결했기 때문에 isOn, isOff를 사용할 수 있음, Any선택시 어떤 클래스 객체인지 알 수 없어 사용 불가 @IBAction func switchImageOnOff(_ sender: UISwitch) { // isOn, isOff : 스위치 객체에서 내된 메소드 /* if sender.isOn{ imgView.image = imgOn } else { imgView.image = imgOff } */ // imgView.image = sender.isOn ? imgOn : imgOff /* 캐시 메모리 사용하지 않고 이미지 불러오기 let lampOnPath = Bundle.main.path(forResource: "lamp_on", ofType: "png") let lampOffPath = Bundle.main.path(forResource: "lamp_off", ofType: "png") let imgOnImage = UIImage(contentsOfFile: lampOnPath!) let imgOffImage = UIImage(contentsOfFile: lampOffPath!) imgView.image = sender.isOn ? imgOnImage : imgOffImage */ // 함수화 imgView.image = sender.isOn ? LoadImage(fileName: "lamp_on", fileType: "png") : LoadImage(fileName: "lamp_off", fileType: "png") } func LoadImage(fileName: String, fileType: String) -> UIImage?{ if let path = Bundle.main.path(forResource: fileName, ofType: fileType){ return UIImage(contentsOfFile: path) } return nil } }
- 이미지 뷰 Aspect Fit : 설정된 이미지 뷰의 크기안에 이미지를 넣을 때 이미지가 갖고 있는 비율에 맞춰 넣어줌, Aspect Fil 설정된 이미지 뷰의 크기 안에 이미지를 꽉 맞게 채우는데, 이미지를 채울 때 긴쪽이 초과 될 수 있음 (가로가 짧고 세로가 길다면, 가로에 맞춰서 이미지 뷰에 꽉 채우는데 세로가 남으므로 세로가 길게 빠져나옴)
- imgOn, imgOff란 변수를 선언해서 미리 이미지를 로드해놓는 것은 캐시로 넣어놔서 속도가 빠를 수 있으나.. 이미지 크기가 커지면 그만큼 메모리를 사용하게 되므로 그때마다 동적 할당 하는 방식이 효율적임 => keyword : contentsOfFile
3. 6개의 이미지 뷰어 만들기
import UIKit class ViewController: UIViewController { @IBOutlet var imgViewer: UIImageView! var index = 0 var imageName:Array = ["01.png", "02.png", "03.png", "04.png", "05.png", "06.png"] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. imgViewer.image = UIImage(named:imageName[index]) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func btnClickPrior(_ sender: UIButton) { print("\(index) / \(imageName.count)") if index > 0 { index -= 1 } else { index = imageName.count-1 } imgViewer.image = UIImage(named:imageName[index]) } @IBAction func btnClickNext(_ sender: UIButton) { print("\(index) / \(imageName.count)") if index < imageName.count-1 { index += 1 } else { index = 0 } imgViewer.image = UIImage(named:imageName[index]) } }
- 결과 화면
3. 데이트 피커
import UIKit class OutClass{ @objc func outFunc(timer: Timer) -> Void{ // userInfo로 self가 넘어왔고, self가 갖고 있는 userInfo값을 바탕으로 ViewController클래스 내부의 변수 lblCurrentTime에 접근할 수 있음 NSLog("%@", #function) let vc = timer.userInfo as! ViewController print(vc.lblCurrentTime.text!) } } class ViewController: UIViewController { let dateFormat = DateFormatter() @IBOutlet var lblCurrentTime: UILabel! @IBOutlet var lblPickerTime: UILabel! override func viewDidLoad() { super.viewDidLoad() let out = OutClass(); // block : 클로져와 같음 Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: {( timer: Timer) -> Void in // #function : 현재 실행 중인 함수 명 NSLog("%@", #function) // NSDate(), Date() let date = Date() self.dateFormat.dateFormat = "yyyy-MM-dd HH:mm:ss EEE" // 클로져에서는 self를 써서 해당 객체에 접근해야 함 self.lblCurrentTime.text = "현재 시간 : " + self.dateFormat.string(from: date) }) // scheduledTemier의 다른 사용 방법 (객체를 넘겨 받을 때, 책과 같음) Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateLabel), userInfo: nil, repeats: true) // 다른 클래스에 있는 함수를 호출해야 할 때, target과 selector 함수는 @objc를 붙여야하며, userInfo에 self를 넘겼다는 것을 볼 것 Timer.scheduledTimer(timeInterval: 1, target: out, selector: #selector(out.outFunc), userInfo: self, repeats: true) } @IBAction func changeDatePicker(_ sender: UIDatePicker) { lblPickerTime.text = "선택 시간 : " + dateFormat.string(from: sender.date) } func updateLabel() -> Void{ NSLog("%@", #function) } }
- 실행 결과
- Time.scheduledTimer라는 메소드의 세 가지 방법 : 다른 객체 전달 없을 때, 객체 전달 받을 때, 객체가 외부 클래스일 때
- Target : 클래스 객체, #selector : 클래스 객체의 Function
- userInfo에 self를 넘겼기에 ViewController로 형변환 가능함, 만약 넘기는게 label이라면 as! UILabel이 될 것
4. 선택 시간과 현재 시간 (분 까지만) 일치 시 배경 화면 바꾸기
import UIKit class ViewController: UIViewController { let dateFormat = DateFormatter() var alamTime = "" var currentTime = "" var count = 0 @IBOutlet var lblCurrentTime: UILabel! @IBOutlet var lblPickerTime: UILabel! override func viewDidLoad() { super.viewDidLoad() Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateLabel), userInfo: nil, repeats: true) } @IBAction func changeDatePicker(_ sender: UIDatePicker) { dateFormat.dateFormat = "yyyy-MM-dd HH:mm:ss EEE" lblPickerTime.text = "선택 시간 : " + dateFormat.string(from: sender.date) dateFormat.dateFormat = "hh:mm aaa" alamTime = dateFormat.string(from: sender.date) } func updateLabel() -> Void{ let date = Date() dateFormat.dateFormat = "yyyy-MM-dd HH:mm:ss EEE" lblCurrentTime.text = "현재 시간 : " + dateFormat.string(from: date) dateFormat.dateFormat = "hh:mm aaa" currentTime = dateFormat.string(from: date) print("\(alamTime) / \(currentTime)") self.view.backgroundColor = alamTime == currentTime ? UIColor.red : UIColor.white } }
- 실행 결과
5. 피커뷰
import UIKit class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate { var fileNameArray: Array = Array
() @IBOutlet var imagePicker: UIPickerView! @IBOutlet var lblFileName: UILabel! @IBOutlet var imageView: UIImageView! override func viewDidLoad() { super.viewDidLoad() // self는 ViewController, dataSource는 UIPickerViewDataSource 프로토콜의 변수 // 그러므로 ViewController는 프로토콜을 상속받음 => 상속 시, 구현해야 할 함수 있는지 들어가 확인 // dataSource = 해당 컴포넌트의 정보를 설정함 (행의 개수 등), 보통 데이터소스와 델리게이트를 같이 씀 imagePicker.dataSource = self // 프로토콜을 상속받을 때 그 안에 명세된 함수를 가져다 쓰기위한 델리게이트 // delegate = 해당 컴포넌트를 갖고 할 수 있는 메소드들가져다 쓰기 위함 imagePicker.delegate = self // 배열에 이미지 넣기 for i in 1...10 { fileNameArray.append(String(format: "%d.jpg", i)) } // 초기 이미지, 라벨 설정 lblFileName.text = fileNameArray[0] imageView.image = UIImage(named: fileNameArray[0]) } // UIPickerViewDataSource 프로토콜에 명세된 함수들 => 옵셔널로 선언되지 않았다면 구현해야 함 // 피커뷰에 보여줄 컬럼의 개수 public func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } // 피커뷰 컴포넌트 안에 갖고있는 각 데이터들의 row number public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return fileNameArray.count } public func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { return 100 } /* // UIPickerViewDelegate 선택 시 타이틀 출력 public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return fileNameArray[row] } */ // UIPickerViewDelegate 선택 시 보여줄 뷰를 설정, 타이틀 출력과 동시 사용 안 됨 public func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { let imageView = UIImageView() imageView.frame = CGRect(x: 0, y: 0, width: 100, height: 100) imageView.image = UIImage(named: fileNameArray[row]) return imageView } // UIPickVierDelegate : 항목 선택 시 호출 public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { lblFileName.text = fileNameArray[row] imageView.image = UIImage(named: fileNameArray[row]) } }
- 실행 결과
6. 피커뷰 컴포넌트 2개
- 위의 소스 중, 컬럼 개수 지정함수와 클릭 후 호출할 함수만 변경
// UIPickerViewDataSource 프로토콜에 명세된 함수들 => 옵셔널로 선언되지 않았다면 구현해야 함 // 피커뷰에 보여줄 컬럼의 개수 public func numberOfComponents(in pickerView: UIPickerView) -> Int { return 2 }
// UIPickVierDelegate : 항목 선택 시 호출 public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { if component == 0{ lblFileName.text = fileNameArray[row] } else { imageView.image = UIImage(named: fileNameArray[row]) } }
7. 경고 창
import UIKit class ViewController: UIViewController { @IBOutlet var imageLamp: UIImageView! var lampOn:Bool = false override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func lampOnClicked(_ sender: UIButton) { if(lampOn){ let alert = UIAlertController(title: "알림", message: "램프가 이미 켜져있습니다", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) } else { lampOn = true imageLamp.image = UIImage(named: "lamp-on.png") } } @IBAction func lampOffClicked(_ sender: UIButton) { if(lampOn){ let alert = UIAlertController(title: "알림", message: "램프를 끄시겠습니까?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "네", style: .default, handler: {(action) in self.lampOn = false self.imageLamp.image = UIImage(named: "lamp-off.png") })) alert.addAction(UIAlertAction(title: "아니요", style: .cancel, handler: nil)) self.present(alert, animated: true, completion: nil) } else { imageLamp.image = UIImage(named: "lamp-off.png") } } @IBAction func lampRemoveClicked(_ sender: UIButton) { let alert = UIAlertController(title: "알림", message: "램프를 제거하시겠습니까?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "아니요, 램프를 키겠습니다", style: .default, handler: {(action) in self.lampOn = true self.imageLamp.image = UIImage(named: "lamp-on.png") })) alert.addAction(UIAlertAction(title: "아니요, 램프를 끄겠습니다", style: .cancel, handler: {(action) in self.lampOn = false self.imageLamp.image = UIImage(named: "lamp-off.png") })) alert.addAction(UIAlertAction(title: "네 램프를 제거합니다", style: .destructive, handler: {(action) in self.lampOn = false self.imageLamp.image = UIImage(named: "lamp-remove.png") })) self.present(alert, animated: true, completion: nil) } }
- 실행 결과
'iOS (교육)' 카테고리의 다른 글
[SWIFT] 6일차 : 스위프트 기본 앱 (0) | 2017.04.29 |
---|---|
[SWIFT] 5일차 : 스위프트 기본 앱 (0) | 2017.04.15 |
[SWIFT] 4일차 : 스위프트 기본 앱 (0) | 2017.04.08 |
[SWIFT] 3일차 : 스위프트 기본 앱 (3) | 2017.04.01 |
[SWIFT] 1일차 : 스위프트 기본 문법 (3) | 2017.03.18 |