일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- flutter rotate
- swift autolayout
- Flutter UIKitView MethodChannel
- 앱 백그라운드 푸시 데이터 저장
- 스위프트 UserDefaults
- swift 문자
- swift sms
- 스위프트
- 스위프트 푸시
- 안드로이드 앨범
- flutter 회전
- silent push
- 스위프트 웹뷰
- 스위프트 카메라
- 안드로이드 FCM
- 플러터 뷰 컨트롤러
- FlutterView MethodChannel
- 안드로이드 에러
- 노티피케이션 익스텐션
- 스위프트 테이블 뷰 셀
- native flutter view
- 안드로이드 바로가기
- Flutter NativeView
- 스위프트 앨범
- Swift flutterview
- 안드로이드 숏컷
- 푸시 데이터 저장
- NotificationService Extension
- 앱 꺼졌을 때 푸시 데이터 저장
- Swift flutterviewcontroller
- Today
- Total
Things take time
[SWIFT] 3일차 : 스위프트 기본 앱 본문
[SWIFT]
1. 현재 시간과 선택 시간(데이트 피커 뷰)이 일치하면 Alert, 경고 창을 띄우며 알겠다는 문구를 입력하면 1분동안 나타나지 않도록 하는 앱 만들기
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)") if(alamTime == currentTime){ if !isCheck{ let alert = UIAlertController(title:"알림", message: "설정된 시간입니다", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "네, 알겠습니다", style: .cancel, handler: nil)) self.present(alert, animated: true, completion: nil) isCheck = true } else { isCheck = false } } }
- 기존 datePicker 앱에서 updateLabel()만 수정
- Alert는 기본적으로 Modal 뷰라고 하여 띄워진 뷰 뒤의 백그라운드가 눌려지지 않는 뷰를 사용한다.
- present를 통해 띄워진 뷰는 dismiss라는 것을 이용하여 내릴 수 있음
2. 웹뷰
import UIKit class ViewController: UIViewController, UIWebViewDelegate { @IBOutlet var urlTextField: UITextField! @IBOutlet var webView: UIWebView! @IBOutlet var indicatorView: UIActivityIndicatorView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. webView.delegate = self } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func goClick(_ sender: UIButton) { let urlString = urlTextField.text webView.loadRequest(URLRequest(url: URL(string: urlString!)!)) } @IBAction func GoNaver(_ sender: UIButton) { webView.loadRequest(URLRequest(url: URL(string: "http://m.naver.com")!)) } @IBAction func GoDaum(_ sender: Any) { webView.loadRequest(URLRequest(url: URL(string: "http://m.daum.net")!)) } @IBAction func loadHTML(_ sender: UIButton) { let htmlString: String = 주석참고 webView.loadHTMLString(htmlString, baseURL: nil) } @IBAction func loadFile(_ sender: UIButton) { if let path = Bundle.main.path(forResource: "file", ofType: "html") { webView.loadRequest(URLRequest(url: URL(string: path)!)) } } // 페이지를 열지 말지를 결정하는, 직전에 호출되는 함수 @available(iOS 2.0, *) public func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool{ print(request.url!) // NSString타입이 String타입보다 내장 메소드를 더 갖고 있기 때문에 형변환 한 것 if let urlString = request.url?.absoluteString as NSString?{ if urlString.contains("daum.net") { return false } } return true } @available(iOS 2.0, *) public func webViewDidStartLoad(_ webView: UIWebView){ indicatorView.startAnimating() } @available(iOS 2.0, *) public func webViewDidFinishLoad(_ webView: UIWebView){ indicatorView.stopAnimating() } @available(iOS 2.0, *) public func webView(_ webView: UIWebView, didFailLoadWithError error: Error){ indicatorView.stopAnimating() // 에러 출력 시 print(error.localizedDescription) } /* 인디케이터 제어 방법 : 코드로 제어 @IBAction func stopWebView(_ sender: UIBarButtonItem) { webView.stopLoading() } @IBAction func refreshWebView(_ sender: UIBarButtonItem) { webView.reload() } @IBAction func priorWebView(_ sender: UIBarButtonItem) { webView.goBack() } @IBAction func forwardWebView(_ sender: UIBarButtonItem) { webView.goForward() } 방법 2 : 스토리보드 상에서 해당 네 개의 버튼을 컨트롤 클릭 후 웹뷰 안으로 드래그 하면 됨 */ }
- App Transport Security has blocked ... 에러 발생 시 => plist 파일에서 +버튼 눌러 App Transport Security Setting 생성, 왼쪽의 화살표 버튼을 아래로 향하게 클릭 후 -> Allow Arbitrary Loads 를 YES로 수정 : Http로 접속시 발생하는 에러로 이 설정을 해줘야 함
- HTMLString = "<h1> HTML String </h1> <p>String 변수를 이용한 웹 페이지</p> <p><a href=\"http://www.google.com\">Google 홈페이지</a>로 이동 </p>"
- file.html을 empty file로 만들어서 직접 작성한 후, 부르는 방법 참고 => Bundle.main XXX, 그리고 해당 파일의 여부를 조사하는 if문을 넣어주는 것이 안정성면에서 좋음
3. 맵뷰, Segmented Control
- 들어가는 개수에 따라 증가되는 Segmented Control에서 각 글자수에 맞춰 너비를 다르게 하고 싶다면 위의 Proportinal to Content로 설정함
- 지도와 같은 기능 사용시엔 사용 설명 없이 사용할 수 없도록 되어있음 -> plist에 포함해야 함(NSLocationWhenInUseUsageDescription)
import UIKit import MapKit class ViewController: UIViewController, CLLocationManagerDelegate { // strong : heap 저장 // weak : 클래스 해제 시 자동 삭제 @IBOutlet weak var mapView: MKMapView! @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var subtitleLabel: UILabel! let locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // 딜리게이트 설정(프로토콜 상속 선행) locationManager.delegate = self // 정확도 설정 locationManager.desiredAccuracy = kCLLocationAccuracyBest // 권한 요청 locationManager.requestWhenInUseAuthorization() // 지도 업데이트 locationManager.startUpdatingLocation() // 디바이스를 갖고있는 유저의 위치를 표시할 것인지에 대한 여부 mapView.showsUserLocation = true } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // 맵뷰에 위치 찍기 func showLocation(latitude lat:CLLocationDegrees, longitude lot:CLLocationDegrees, delta span:Double){ // 위도 경도를 갖고 location값을 만들어, setRegion에 대입 let location = CLLocationCoordinate2DMake(lat, lot) let mkSpan = MKCoordinateSpanMake(span, span) mapView.setRegion(MKCoordinateRegionMake(location, mkSpan), animated: true) } // 마커 찍기 func showAnnotation(latitude lat:CLLocationDegrees, longitude lot:CLLocationDegrees, delta span:Double, pinTitle title: String, pinSubTitle subTitle: String){ let annotation = MKPointAnnotation() annotation.coordinate = CLLocationCoordinate2DMake(lat, lot) annotation.title = title annotation.subtitle = subTitle mapView.addAnnotation(annotation) titleLabel.text = title subtitleLabel.text = subTitle } @available(iOS 6.0, *) public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){ /* // guard : 옵셔널 데이터를 검사, 벗겨 낼수 없다면 else로 가기때문에 if let보다 depth가 1이 덜 깊어짐, 만약 unwrapping을 성공했다면 그 밑에 줄을 실행하게 됨 guard let location = locations.last else { return } // code */ // last : 배열 마지막 값 리턴 guard let location = locations.last else { return } // CLGeocoder : 주소와 위도 경도를 변환해주는 클래스 CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in if let err = error { print(err.localizedDescription) locationManager.stopUpdatingLocation() return } if let unwrappedPlacemarks = placemarks, let placemark = unwrappedPlacemarks.first{ print(placemark) // ?? "" : 해당 옵셔널 값이 없으면 ""로 초기화하라 let address = String(format: "%@ %@ %@ %@ %@", placemark.country ?? "", placemark.administrativeArea ?? "", placemark.locality ?? "", placemark.thoroughfare ?? "", placemark.subThoroughfare ?? "") self.showLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude, delta: 0.01) self.showAnnotation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude, delta: 0.01, pinTitle:"현재위치", pinSubTitle: address) } }) locationManager.stopUpdatingLocation() } @IBAction func changeSeg(_ sender: UISegmentedControl) { print(sender.selectedSegmentIndex) if sender.selectedSegmentIndex == 0{ // 현재 위치 locationManager.startUpdatingLocation() } else if sender.selectedSegmentIndex == 1{ // 강남역 showLocation(latitude: 37.498248, longitude: 127.027621, delta: 0.01) showAnnotation(latitude: 37.498248, longitude: 127.027621, delta: 0.01, pinTitle: "강남역", pinSubTitle: "이다") } else if sender.selectedSegmentIndex == 2{ // 집 showLocation(latitude: 37.458329, longitude: 127.160148, delta: 0.01) showAnnotation(latitude: 37.458329, longitude: 127.160148, delta: 0.01, pinTitle: "집", pinSubTitle: "이다") } } }
- 중요 부분 : 마커 찍기, 현재 위치 로딩, guard let, 핸들러 부분
4. 페이지 컨트롤 : 페이지 컨트롤 사용할 때, 화면의 좌우를 꽉차게 해야 옆 부분 클릭해도 잘 넘어감, 근데 스왑(터치)으로 넘어가는 방식을 더 사용하기에 잘 사용하지 않는 방식
import UIKit class ViewController: UIViewController { var imageArray = Array() @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var pageControl: UIPageControl! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. for i in 1...6{ imageArray.append(String(format: "%02d.png",i)) } imageView.image = UIImage(named: imageArray[0]) pageControl.numberOfPages = imageArray.count pageControl.currentPage = 0 pageControl.pageIndicatorTintColor = UIColor.red pageControl.currentPageIndicatorTintColor = UIColor.yellow } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func changepage(_ sender: UIPageControl) { imageView.image = UIImage(named: imageArray[sender.currentPage]) } }
5. 페이지 컨트롤2 : 좌우로 스왑하면서 아래 페이지 컨트롤이 자동적으로 변할 수 있도록
import UIKit class ViewController: UIViewController, UIScrollViewDelegate { @IBOutlet weak var scrollView: UIScrollView! var pageControl = UIPageControl() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. scrollView.delegate = self scrollView.contentSize = CGSize(width: view.frame.width * 6, height: scrollView.frame.height) // 가로로 긴 스크롤 뷰를 만들 것 for i in 0...5{ // x, y는 생성할 위치의 시작 저좌표 값 let imageView = UIImageView(frame: CGRect(x: CGFloat(i) * view.frame.width , y: 0, width: view.frame.width, height: view.frame.height)) imageView.image = UIImage(named: String(format: "%02d.png", i+1)) scrollView.addSubview(imageView) } // 페이지 컨트롤 동적 할당하기 pageControl = UIPageControl(frame: CGRect(x: 0, y: scrollView.frame.height - 37, width: view.frame.width, height: 37)) pageControl.currentPage = 0 pageControl.numberOfPages = 6 view.addSubview(pageControl) // 버튼 동적 할당하기 let button = UIButton(frame: CGRect(x: 100, y: 100, width: 200, height: 150)) button.backgroundColor = UIColor.red button.addTarget(self, action: #selector(self.buttonClicked), for: .touchUpInside) view.addSubview(button) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func buttonClicked(sender: UIButton){ NSLog("file info: %@", #file) NSLog("function info: %@", #function) NSLog("line info: %d", #line) } @available(iOS 2.0, *) public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView){ pageControl.currentPage = (Int)(scrollView.contentOffset.x / scrollView.frame.width) } }
'iOS (교육)' 카테고리의 다른 글
[SWIFT] 6일차 : 스위프트 기본 앱 (0) | 2017.04.29 |
---|---|
[SWIFT] 5일차 : 스위프트 기본 앱 (0) | 2017.04.15 |
[SWIFT] 4일차 : 스위프트 기본 앱 (0) | 2017.04.08 |
[SWIFT] 2일차 : 스위프트 기본 앱 (0) | 2017.03.25 |
[SWIFT] 1일차 : 스위프트 기본 문법 (3) | 2017.03.18 |