Swift4 tip 2

Programming/Swift 2019. 12. 17. 13:49 Posted by 파란크리스마스

출처

UITableView 초기화

class MainViewController: UIViewController {
    
    override func loadView() {
        super.loadView();
        
        self.initWebView(activityIndicator: self.activityIndicator1)
        self.setUrl(hostUrl: MainViewController.url_archim_host, baseUrl: MainViewController.url_archim_base, appUrl: url_archim)
        
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        //appDelegate.viewController = self
        
        //current_orientation = UIInterfaceOrientationMask.Portrait
        
        // 배경색
        self.navigationController?.navigationBar.barTintColor = UIColor.white
        /*
        // 중앙타이틀
        self.navigationController?.navigationBar.topItem?.title = "중앙타이틀"
        // 좌우 글자색
        self.navigationController?.navigationBar.tintColor = UIColor.red
        // 왼쪽 타이틀
        self.navigationItem.leftBarButtonItem?.title = "왼쪽메뉴"
        */
        
        /*
        // titleView로 사용할 Label을 생성
        var frame = CGRect(x: 0, y: 0, width: 200, height: 21)
        let label = UILabel(frame: frame)
        label.text = "이것을 타이틀로 사용합니다"
        // viewController의 titleView를 생성한 Label로 셋업
        self.navigationController?.navigationBar.topItem?.titleView = label
        */
        
        // 중앙
        // let logo = UIImage(named: "main_logo.png")
        let logo = Utiltiy.resizeImage(image: UIImage(named: "main_logo.png")!, targetSize: CGSize(width: 140, height: 32))
        let imageView = UIImageView(image: logo)
        self.navigationItem.titleView = imageView
        
        //
        let leftBarItemImage = Utiltiy.resizeImage(image: UIImage(named: "main_gnb.png")!, targetSize: CGSize(width: 50, height: 50))
        self.navigationItem.leftBarButtonItem?.tintColor = UIColor(rgb: 0x636363)
        self.navigationItem.leftBarButtonItem?.image = leftBarItemImage;
        self.navigationItem.leftBarButtonItem?.imageInsets = UIEdgeInsets(top: 0, left: -18, bottom: 0, right: 0)
        
        //
        let rightBarItemImage = Utiltiy.resizeImage(image: UIImage(named: "main_list.png")!, targetSize: CGSize(width: 50, height: 50))
        self.navigationItem.rightBarButtonItem?.tintColor = UIColor(rgb: 0x636363)
        self.navigationItem.rightBarButtonItem?.image = rightBarItemImage;
        self.navigationItem.rightBarButtonItem?.imageInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: -18)
 
        /*
        // setTitlePositionAdjustment 함수 호출
        self.navigationItem.leftBarButtonItem?.setTitlePositionAdjustment(UIOffset(horizontal: 30, vertical: 30), for: UIBarMetrics.compact)
        */
        
        /*
        // UIBarButtonItem 추가
        // http://mtsparrow.blogspot.com/2016/01/blog-post.html
        let leftTarget = self.navigationItem.leftBarButtonItem?.target
        let leftAction = self.navigationItem.leftBarButtonItem?.action
        let leftButton = UIBarButtonItem(image: UIImage (named: "main_gnb.png"), style: UIBarButtonItem.Style.plain, target: leftTarget, action: leftAction)
        let negativeSpacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
        negativeSpacer.width = -16
        //self.navigationItem.leftBarButtonItem = logo2
        self.navigationItem.setLeftBarButtonItems([negativeSpacer, leftButton], animated: false)
        */
    }

UITableViewController - Row 선택

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        // 선택된 index 순서 출력
        // print(indexPath.row)
        
        let cell = super.tableView(tableView, cellForRowAt: indexPath) as! UITableViewVibrantCell
        
        if case cell.reuseIdentifier = "menu_quality" {
            let storyboard = UIStoryboard(name : "MainStoryboard_iPhone", bundle : nil)
            let nextViewController = storyboard.instantiateViewController(withIdentifier: "TabBarController") as! NiaspMainViewController
            self.present(nextViewController, animated: true, completion: nil)
        }
    }

uitableview에서 cell클릭시 다음 view로 데이터 넘기기

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let vc = segue.destination as! infoPUBG_kind
        //vc.value2 = value
        let cell = sender as! UITableViewCell
        let indexPath = tableView.indexPath(for: cell)
        vc.kindTitle = infoList[(indexPath?.row)!]//내가누른 cell의 text
        vc.kindRow = (indexPath?.row)!//내가누른 cell의 row값
    }

SideMenu

SideMenuNavigationController.swift

@objcMembers
open class SideMenuNavigationController: UINavigationController {

SideMenuManager

@objcMembers public class SideMenuManager : NSObject {

    @objc public enum PresentDirection : Int {

        case left

        case right
    }

    /// Default instance of SideMenuManager.
    public static let `default`: SideMenu.SideMenuManager

    /// Default instance of SideMenuManager (objective-C).
    public class var defaultManager: SideMenu.SideMenuManager { get }

    /// The left menu.
    open var leftMenuNavigationController: SideMenu.SideMenuNavigationController?

    /// The right menu.
    open var rightMenuNavigationController: SideMenu.SideMenuNavigationController?

    /**
         Adds screen edge gestures for both left and right sides to a view to present a menu.
    
         - Parameter toView: The view to add gestures to.
    
         - Returns: The array of screen edge gestures added to `toView`.
         */
    public func addScreenEdgePanGesturesToPresent(toView view: UIView) -> [UIScreenEdgePanGestureRecognizer]

    /**
        Adds screen edge gestures to a view to present a menu.
        
        - Parameter toView: The view to add gestures to.
        - Parameter forMenu: The menu (left or right) you want to add a gesture for.
    
        - Returns: The screen edge gestures added to `toView`.
        */
    public func addScreenEdgePanGesturesToPresent(toView view: UIView, forMenu side: SideMenu.SideMenuManager.PresentDirection) -> UIScreenEdgePanGestureRecognizer

    /**
     Adds a pan edge gesture to a view to present menus.
     
     - Parameter toView: The view to add a pan gesture to.
     
     - Returns: The pan gesture added to `toView`.
     */
    public func addPanGestureToPresent(toView view: UIView) -> UIPanGestureRecognizer
}

extension SideMenuManager {

    @available(*, deprecated, renamed: "leftMenuNavigationController")
    open var menuLeftNavigationController: SideMenu.SideMenuNavigationController?

    @available(*, deprecated, renamed: "rightMenuNavigationController")
    open var menuRightNavigationController: SideMenu.SideMenuNavigationController?

SideMenu 버튼 클릭 이벤트

import SideMenu

class SideMenuTableViewController: UITableViewController {

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        print(indexPath.row)
        
        if case indexPath.row = 3 {
            //SettingsMainViewController *comChange = [[SettingsMainViewController alloc] init];
            //[self.navigationController pushViewController:comChange animated:NO];
            //var comChange : SettingsMainViewController
            
            /*
            let storyboard : UIStoryboard = self.storyboard!
            let nextView = storyboard.instantiateViewController(identifier: "MainStoryboard_iPhone")
            self.present(nextView, animated: true, completion: nil)
            */
            
            let storyboard = UIStoryboard(name : "MainStoryboard_iPhone", bundle : nil)
            let nextView = storyboard.instantiateInitialViewController()
            self.present(nextView!, animated: true, completion: nil)
        }
    }

SideMenuNavigationControllerDelegate

extension MainViewController: SideMenuNavigationControllerDelegate {
    
    func sideMenuWillAppear(menu: SideMenuNavigationController, animated: Bool) {
        print("SideMenu Appearing! (animated: \(animated))")
    }
    
    func sideMenuDidAppear(menu: SideMenuNavigationController, animated: Bool) {
        print("SideMenu Appeared! (animated: \(animated))")
    }
    
    func sideMenuWillDisappear(menu: SideMenuNavigationController, animated: Bool) {
        print("SideMenu Disappearing! (animated: \(animated))")
    }
    
    func sideMenuDidDisappear(menu: SideMenuNavigationController, animated: Bool) {
        print("SideMenu Disappeared! (animated: \(animated))")
    }
}

activeDelegate (SideMenuNavigationController.swift)

@objcMembers
open class SideMenuNavigationController: UINavigationController {

    /// Delegate for receiving appear and disappear related events. If `nil` the visible view controller that displays a `SideMenuNavigationController` automatically receives these events.
    public weak var sideMenuDelegate: SideMenuNavigationControllerDelegate?

... 생략 ...

private extension SideMenuNavigationController {

    weak var activeDelegate: SideMenuNavigationControllerDelegate? {
        guard !view.isHidden else { return nil }
        if let sideMenuDelegate = sideMenuDelegate { return sideMenuDelegate }
        return findViewController as? SideMenuNavigationControllerDelegate
    }

    var findViewController: UIViewController? {
        foundViewController = foundViewController ?? presentingViewController?.activeViewController
        return foundViewController
    }



댓글을 달아 주세요

Swift4 tip

Programming/Swift 2018. 8. 27. 10:14 Posted by 파란크리스마스

출처

Dictionary to JSON

출처 : Convert Dictionary to JSON in Swift - Stack Overflow

        let jsonData = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions.prettyPrinted)
        let jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String
        print(jsonString)

화면전환, 파라미터 전달

출처 : Swift 화면 전환 기법: 뷰 컨트롤러, 내비게이션 컨트롤러, 세그웨이 : 네이버 블로그

    func native_video_recording(_ data : NSDictionary) { 
        let vcRecord = self.storyboard!.instantiateViewController(withIdentifier: "vcRecord") as! RecordController // 1
        vcRecord.setParamData(data) // 파라미터 전달
        vcRecord.modalTransitionStyle = UIModalTransitionStyle.crossDissolve // 2
        self.present(vcRecord, animated: true) // 3
    }

카메라 리소스 구하기

출처 : GitHub - parthibanios/custom-Video-Recording-Swift-3.0: Record video using AVCapture AVFoundation framework

    //MARK:- Setup Camera
    func setupSession() -> Bool {
        
        //captureSession.sessionPreset = AVCaptureSessionPresetHigh
        //1080
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
        
        // Setup Camera
        let camera = AVCaptureDevice.default(for: .video)
        do {
            let input = try AVCaptureDeviceInput(device: camera!)
            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
                activeInput = input
            }
        } catch {
            print("Error setting device video input: \(error)")
            return false
        }
        
        // Setup Microphone
        let microphone = AVCaptureDevice.default(for: .audio)
        do {
            let micInput = try AVCaptureDeviceInput(device: microphone!)
            if captureSession.canAddInput(micInput) {
                captureSession.addInput(micInput)//addInput(micInput)
            }
        } catch {
            print("Error setting device audio input: \(error)")
            return false
        }
        movieOutput.maxRecordedDuration = CMTimeMake(9, 1)
        
        // Movie output
        if captureSession.canAddOutput(movieOutput) {
            captureSession.addOutput(movieOutput)
        }
        
        return true
    }

도큐먼트 디렉토리 구하기 - UIFileSharingEnabled 설정의 Root 경로

출처 : Swift로 파일 다루기 :

Eth Developer's Lab

    //EDIT 1: I FORGOT THIS AT FIRST
    func getMp4PathURL() -> URL? {
        /*
        let directory = NSTemporaryDirectory() as NSString
        
        if directory != "" {
            let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
            return URL(fileURLWithPath: path)
        }
        return nil
        */
        
        // 도큐먼트 디렉토리 구하기 - UIFileSharingEnabled의 Root 경로
        guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil }
        let fileName = NSUUID().uuidString + ".mp4"
        let fileURL = documentsDirectory.appendingPathComponent(fileName)
        
        /*
        print(imageURL)
        do {
            let imageData = try Data(contentsOf: imageURL)
            return UIImage(data: imageData)
        } catch let err as NSError {
            print("이미지 로딩 에러 : \(err)")
        }
        */
        
        return fileURL
    }

Swift4 : Alamofire 프로젝트에 추가하기

출처 : [iOS / Swift4] Alamofire 사용하기 | ry4nkim

Podfile 파일 편집

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'project' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  project 'project.xcodeproj'

  # Pods for project
  pod 'Firebase/Core'
  pod 'Firebase/Messaging'
  pod 'Alamofire', '~> 4.7'

end

pod install

$ pod install
Analyzing dependencies
Downloading dependencies
Installing Alamofire (4.7.3)
Installing Firebase 5.4.0
Installing FirebaseAnalytics (5.0.1)
Using FirebaseCore (5.0.5)
Using FirebaseInstanceID (3.1.1)
Using FirebaseMessaging (3.0.3)
Using GoogleToolboxForMac (2.1.4)
Using Protobuf (3.6.0)
Installing nanopb (0.3.8)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 3 dependencies from the Podfile and 9 total pods installed.
 
[!] Automatically assigning platform `ios` with version `9.3` on target `project` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.

Alamofire 파일 업로드, 결과 JSON 파싱

출력 : swift3 - upload image to server using Alamofire - Stack Overflow, ios - How to parse JSON response from Alamofire API in Swift? - Stack Overflow

        Alamofire.upload(multipartFormData: { (multipartFormData) in
            /*
            for (key, value) in parameters {
                multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
            }
            */
            multipartFormData.append("\(jsonString)".data(using: String.Encoding.utf8)!, withName: "json_str")
            
            /*
            if let data = imageData{
                multipartFormData.append(data, withName: "image", fileName: "image.png", mimeType: "image/png")
            }
            */
            multipartFormData.append(mp4FileUrl, withName: "test.mp4")
            
        }, usingThreshold: UInt64.init(), to: self.upload_url, method: .post, headers: headers) { (result) in
            switch result{
            case .success(let upload, _, _):
                upload.responseJSON { response in
                    print("Succesfully uploaded")
                    if let err = response.error {
                        print(err)
                        onCompletion?(nil, err)
                        return
                    }
                    if let result = response.result.value {
                        let JSON = result as! NSDictionary
                        print(JSON)
                        onCompletion?(JSON, nil)
                    }
                }
            case .failure(let error):
                print("Error in upload: \(error.localizedDescription)")
                onCompletion?(nil, error)
            }
        }

Timer, String format

출처 : ios - Swift - Update/Refresh Label that Displays Time - Stack Overflow

    let movieOutput = AVCaptureMovieFileOutput()
    var durationTimer: Timer?

    //MARK:- Setup Camera
    func setupSession() -> Bool {
        
        //captureSession.sessionPreset = AVCaptureSessionPresetHigh
        //1080
        captureSession.sessionPreset = AVCaptureSession.Preset.hd1920x1080
        
        // Setup Camera
        // 생략
        // Setup Microphone
        // 생략
 
        // 녹화 시간 제한
        movieOutput.maxRecordedDuration = CMTimeMake(300, 1)
        
        return true
    }

    @IBAction func startRecording() {

        if movieOutput.isRecording == false {
        
// ... 생략 ...
            
            self.seconds = 0
            self.durationTimer = Timer(timeInterval: 1.0, target: self, selector: #selector(self.refreshDurationLabel), userInfo: nil, repeats: true)
            RunLoop.current.add(self.durationTimer!, forMode: RunLoopMode.commonModes)
            self.durationTimer?.fire()
        } else {
            self.durationTimer?.invalidate()
            self.durationTimer = nil
            self.seconds = 0
            //self.durationTxt.text = secondsToFormatTimeFull(second: 0)
            stopRecording()
        }
    }

    func secondsToFormatTimeFull(second: Int)->String {
        let sec : Int = second % 60
        let min : Int = second / 60
        return String(format : "%02d:%02d", min, sec)
    }

    @objc func refreshDurationLabel() {
        self.durationTxt.text = secondsToFormatTimeFull(second: self.seconds)
        seconds = seconds + 1
    }

연락처 조회, 선택, WebView 자바스크립트 호출(evaluateJavaScript)

출처 : ContactsUISample/ViewController.swift at master · koogawa/ContactsUISample · GitHub
[SWIFT] 주소록에 저장된 데이터 불러오기 - Things take time - 티스토리

import Contacts
import ContactsUI

class WebViewBase : UIViewController, CNContactPickerDelegate {

    func native_show_contacts() {
        let pickerViewController = CNContactPickerViewController()
        pickerViewController.delegate = self
        
        // Display only a person's phone, email, and postal address
        let displayedItems = [CNContactPhoneNumbersKey, CNContactEmailAddressesKey, CNContactPostalAddressesKey]
        pickerViewController.displayedPropertyKeys = displayedItems
        
        // Show the picker
        self.present(pickerViewController, animated: true, completion: nil)
    }

    // MARK: CNContactPickerDelegate methods
    // Called when a property of the contact has been selected by the user.
    func contactPicker(picker: CNContactPickerViewController, didSelectContactProperty contactProperty: CNContactProperty) {
        //
    }
    
    func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
        // You can fetch selected name and number in the following way
        
        // user name
        let userName:String = contact.givenName
        
        let name = contact.familyName + contact.givenName
        //print(name)
        
        var primaryPhoneNumberStr:String = ""
        
        if (!contact.phoneNumbers.isEmpty) {
            // user phone number
            let userPhoneNumbers:[CNLabeledValue<cnphonenumber>] = contact.phoneNumbers
            let firstPhoneNumber:CNPhoneNumber = userPhoneNumbers[0].value
            
            
            // user phone number string
            primaryPhoneNumberStr = firstPhoneNumber.stringValue
        }
        
        //print("phonenum = \(primaryPhoneNumberStr)")
        
        webView.evaluateJavaScript("setContract('\(name)', '\(primaryPhoneNumberStr)')")
    }
    
    // Called when the user taps Cancel.
    func contactPickerDidCancel(picker: CNContactPickerViewController) {
        //
    }
}

댓글을 달아 주세요

Swift4 - WKWebView 에서 console.log 사용하기

Programming/Swift 2018. 7. 2. 13:13 Posted by 파란크리스마스

출처

Code

    func initWebView(activityIndicator: UIActivityIndicatorView) {
        // 생략...
        contentController.add(self, name: "native_console_log")
        // 생략...
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if(message.name == "native_console_log") {
            native_console_log(didReceive: message)
        }
    }

    func native_console_log(didReceive message: WKScriptMessage) {
        print(NSString(string: "console.log: \(message.body)"))
    }
 
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        #if CONSOLE_LOG
            let js = "var console = { log: function(message) { webkit.messageHandlers.native_console_log.postMessage(JSON.stringify(message)) } }"
            webView.evaluateJavaScript(js)
        #endif
    }

빌드 옵션 추가

댓글을 달아 주세요

Swift - 외부라이브러리 사용

Programming/Swift 2017. 7. 1. 17:15 Posted by 파란크리스마스

Swift - 외부라이브러리 사용

출처 : DLRadioButton
Seorenn SIGSEGV: Swift 프로젝트에서 Objective-C 코드를 함께 사용하기

외부라이브러리 파일 추가

파일 추가 옵션 선택

브릿지 헤더 파일 생성

브릿지 헤더 파일 설정

자동으로 설정되지만 설정이 되지 않았을 경우 아래와 같이 설정 필요

Button Type 변경

Button Type 변경 전

Button Type 변경 후

Button 라디오버튼의 경우 그룹으로 묶기

Button 라디오버튼 하나의 이벤트 생성


Button 라디오버튼 이벤트 구현

    @IBAction func optionClicked(_ sender: DLRadioButton) {
        print(sender.currentTitle!)

        if (sender == radio1) { // (sender.currentTitle == "석굴암") {
            imageView.image = image1
        } else if (sender.currentTitle == "남대문") {
            imageView.image = image2
        } else if (sender.currentTitle == "독립기념관") {
            imageView.image = image3
        }
    }

댓글을 달아 주세요

  1. 2017.07.11 22:26  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

Swift - Layout 가운데 정렬

Programming/Swift 2017. 7. 1. 10:07 Posted by 파란크리스마스

출처 : IOS 오토레이아웃(AUTOLAYOUT) 사용패턴1 화면 가운데 버튼 배치하기

Top, Width, Height 설정

가운데 정렬


상대 좌표 배치

수평 상대 좌표 설정

수직 상대 좌표 배치

멀티터치 옵션 설정

댓글을 달아 주세요

Swift - Free Draw

Programming/Swift 2017. 7. 1. 09:46 Posted by 파란크리스마스

출처 : Freehand drawing on iOS in Swift - Ilya Puchka


    override func touchesBegan(_ touches: Set<uitouch>, with event: UIEvent?) {
        if let touch = touches.first {
            messageLabel.text = "touchesBegan"
            tapCountLabel.text = String(touch.tapCount)
            touchCountLabel.text = String(touches.count)
            
            lastPoint = touch.location(in: drawImageView)
        }
    }
    
    override func touchesMoved(_ touches: Set<uitouch>, with event: UIEvent?) {
        if let touch = touches.first {
            messageLabel.text = "touchesMoved"
            tapCountLabel.text = String(touch.tapCount)
            touchCountLabel.text = String(touches.count)
            
            lineWidth = CGFloat(Int(textLineWidth.text!)!);
            
            UIGraphicsBeginImageContext(drawImageView.frame.size)
            if let context = UIGraphicsGetCurrentContext() {
                context.setLineWidth(lineWidth)
                context.setStrokeColor(lineColor)
                context.setLineCap(CGLineCap.round)
                
                drawImageView.image?.draw(in: CGRect(origin: CGPoint(x : 0, y : 0), size: drawImageView.frame.size))
                
                context.move(to: lastPoint)
                let currentPoint = touch.location(in: drawImageView)
                context.addLine(to : currentPoint)
                context.strokePath()
                
                drawImageView.image = UIGraphicsGetImageFromCurrentImageContext()
                
                lastPoint = currentPoint
            }
            UIGraphicsEndImageContext()
        }
    }

    override func touchesEnded(_ touches: Set<uitouch>, with event: UIEvent?) {
        if let touch = touches.first {
            messageLabel.text = "touchesEnded"
            tapCountLabel.text = String(touch.tapCount)
            touchCountLabel.text = String(touches.count)
        }
    }


댓글을 달아 주세요

Swift - 예외처리

Programming/Swift 2017. 7. 1. 09:28 Posted by 파란크리스마스

출처 : Swift 에러 (Error) 처리, 예외 상황 다루기 (try, throws, defer 등) : 네이버 ...

    enum ParseError : Error {
        case OverSize
        case UnderSize
        case InvalidFormat(value : String)
        case InvalidData(value : String)
    }

예외발생

    func parseTime(timeString : NSString) throws -> Time {
        
        var retTime = Time(hour : 0, min : 0, sec : 0)
        
        guard timeString.length == 8 else {
            if timeString.length > 8 {
                throw ParseError.OverSize
            } else {
                throw ParseError.UnderSize
            }
        }
        
        if let hour = Int(timeString.substring(to: 2)) {
            print(hour)
            guard hour >= 0 && hour < 24 else {
                throw ParseError.InvalidFormat(value: "시간")
            }
            
            retTime.hour = hour
        } else {
            throw ParseError.InvalidFormat(value: "시간")
        }
        
        if let min = Int(timeString.substring(with : NSRange(location : 3, length : 2))) {
            print(min)
            guard min >= 0 && min < 60 else {
                throw ParseError.InvalidFormat(value: "분")
            }
            
            retTime.min = min
        } else {
            throw ParseError.InvalidFormat(value: "분")
        }
        
        if let sec = Int(timeString.substring(from : 6)) {
            print(sec)
            guard sec >= 0 && sec < 60 else {
                throw ParseError.InvalidFormat(value: "초")
            }
            
            retTime.sec = sec
        } else {
            throw ParseError.InvalidFormat(value: "초")
        }
        
        return retTime		
    }

예외처리

    func getPartTime(timeString : NSString, type : String) {
        do {
            let time = try parseTime(timeString : timeString)
            
            switch type {
            case "hour":
                print("\(time.hour)시")
            case "min":
                print("\(time.min)분")
            case "sec":
                print("\(time.sec)초")
            default:
                print("입력값 배당 시간 정보 없음")
            }
            
        }
        catch ParseError.OverSize {
            print("입력 문자열이 깁니다.")
        }
        catch ParseError.UnderSize {
            print("입력 문자열이 짧습니다.")
        }
        catch ParseError.InvalidData(let part) {
            print("입력값의 \(part)에 해당하는 형식 오류")
        }
        catch ParseError.InvalidFormat(let part) {
            print("입력값의 \(part)에 해당하는 값 오류")
        }
        catch {
            print("알 수 없는 오류")
        }
    }

댓글을 달아 주세요

Swift - UITableView

Programming/Swift 2017. 6. 17. 15:25 Posted by 파란크리스마스

출처 : [IOS/Swift] Custom TableView Cell 만들기 - 코딩하는 빵 - Tistory

//
//  ViewController.swift
//  TableView2
//
//  Created by bluesanta on 2017. 6. 10..
//  Copyright © 2017년 bluesanta. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var toDoArray = ["영화보기", "야구보기", "수영하기"]

    @IBOutlet weak var toDoTableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        self.toDoTableView.dataSource = self
        self.toDoTableView.delegate = self;
    }
    
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return toDoArray.count
    }
    
    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "toDoCell", for:indexPath)
        cell.textLabel?.text = toDoArray[indexPath.row]
        return cell
    }
    
    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // 선택 이벤트
    }
}

Custom Cell

Custom Cell Class 생성 및 지정

Custom Cell 사용

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tvCell", for:indexPath) as! MovieTableViewCell
        //cell.textLabel?.text = movieArray[indexPath.row].title
        cell.thumbnailImageView.image = nil
        cell.titleLabel.text = movieArray[indexPath.row].title
        cell.genreLabel.text = movieArray[indexPath.row].genre
        cell.ratingLabel.text = movieArray[indexPath.row].ratingAverage
        
        /*
        if let titleLabel =  cell.viewWithTag(11) as? UIImageView {
            titleLabel.text = movieArray[indexPath.row].title
        }
        */
    
        return cell
    }

TableView 갱신

           // 메일 쓰레드에서 화면 갱신
            DispatchQueue.main.async {
                self.tvMovie.reloadData()
            }

테이블 상단 공백 제거

- Adjust Scroll View Inserts 체크 제거

댓글을 달아 주세요

  1. CC Ryu 2017.06.18 13:38  댓글주소  수정/삭제  댓글쓰기

    우와 정리된 내용 잘 봤습니다! ^^

Swift - JSON 파싱

Programming/Swift 2017. 6. 17. 12:43 Posted by 파란크리스마스

json 파싱

        let jsonString = "{ \"name\":\"test\", \"age\":30 }"
        if let data = jsonString.data(using: .utf8) {
            do {
                if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject] {
                    
                    print(json["name"] ?? "")
                    print(json["age"] ?? 0)
                }
            } catch {
                print("JSON 파싱 에러")
            }
        }

원격호출 json 파싱

let urlString = "http://115.68.183.178:2029/hoppin/movies?order=releasedateasc&count=10&page=1&version=1&genreId="
        guard let url = URL(string: urlString) else { return }
        
        let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
            guard let data = data,
            let httpRes = response as? HTTPURLResponse, httpRes.statusCode == 200 else {
                return
            }

            if let error = error {
                print(error.localizedDescription)
                return;
            }
            
            do {
                if let jsonDic = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject] {
                    print(jsonDic)
                    
                    guard let totalInfo = jsonDic["hoppin"] as? [String : AnyObject],
                        let totalCount = totalInfo["totalCount"] as? String,
                        let movies = totalInfo["movies"] as? [String :AnyObject],
                        let movieArray = movies["movie"] as? [[String:AnyObject]] else {return}
                    
                    print(totalCount)
                    print(movies)
    
                    for info in movieArray {
                        print(info["title"] ?? "")
                        print(info["thumbnailImage"] ?? "")
                        
                        let movieInfo = MovieInfo(title : info["title"] as? String,
                            thumbnailUrl : info["thumbnailImage"] as? String,
                            genre : info["genreNames"] as? String,
                            ratingAverage : info["ratingAverage"] as? String)
                        self.movieArray.append(movieInfo)
                    }
                    
                    
                }
            } catch {
                print("JSON 파상 에러")
            }
            
            print("JSON 파싱 완료")
            
            // 메일 쓰레드에서 화면 갱신
            DispatchQueue.main.async {
                self.tvMovie.reloadData()
            }
        })
        
        print("JSON 파싱 시작")
        task.resume()

json 파싱 함수로 구현

    func parseJSONString(jsonString : String) -> [String:AnyObject]? {
        guard let data = jsonString.data(using: .utf8) else {
            return nil
        }
        
        do {
            if let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject] {
                print(json);
                return json
            }
        } catch {
            print("JSON 파싱 에러")
        }

        return nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let jsonString = "{ \"name\":\"test\", \"age\":30 }"
        if let jsonDic = self.parseJSONString(jsonString: jsonString) {
            print(jsonDic["name"] ?? "")
            print(jsonDic["age"] ?? 0)
        }
    }

댓글을 달아 주세요

Swift - OpenAPI 사용하기(XMLParser 사용)

Programming/Swift 2017. 6. 17. 11:19 Posted by 파란크리스마스

출처 : [iOS/Swift] XML 파싱하기 :: 고무망치

OPEN API 호출 및 XML 파싱

class TableViewController: UITableViewController, XMLParserDelegate {

    var xmlParser = XMLParser()
    
    var currentElement = ""                // 현재 Element
    var movieItems = [[String : String]]() // 영화 item Dictional Array
    var movieItem = [String: String]()     // 영화 item Dictionary
    
    var pubTitle = "" // 영화 제목
    var contents = "" // 영화 내용
    
    func requestMovieInfo() {
        // OPEN API 주소
        let url = "http://api.koreafilm.or.kr/openapi-data2/service/api105/getOpenDataList"
        
        guard let xmlParser = XMLParser(contentsOf: URL(string: url)!) else { return }
        
        xmlParser.delegate = self;
        xmlParser.parse()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()   
        requestMovieInfo()
    }
    
    // XMLParserDelegate 함수
    // XML 파서가 시작 테그를 만나면 호출됨
    public func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:])
    {
        currentElement = elementName
        if (elementName == "item") {
            movieItem = [String : String]()
            pubTitle = ""
            contents = ""
        }
    }
    
    // XML 파서가 종료 테그를 만나면 호출됨
    public func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
    {
        if (elementName == "item") {
            movieItem["title"] = pubTitle;
            movieItem["contents"] = contents;
            
            movieItems.append(movieItem)
        }
    }
    
    // 현재 테그에 담겨있는 문자열 전달
    public func parser(_ parser: XMLParser, foundCharacters string: String)
    {
        if (currentElement == "contents") {
            contents = string
        } else if (currentElement == "pubtitle") {
            pubTitle = string
        }
    }

스토리 보드에서 초기 뷰컨트롤러 지정하기

is initial view controller 체크 박스 선택

XML 결과 보여주기

withIdentifier 설정

코드

    // MARK: - Table view data source
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return self.movieItems.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "movieCell", for: indexPath)
     
        // Configure the cell...
        cell.textLabel?.text = movieItems[indexPath.row]["title"]
     
        return cell
    }

HTTP 접속 오류 해결 하기

오류 메시지 : App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

댓글을 달아 주세요

Swift - 페이지 이동

Programming/Swift 2017. 6. 17. 09:54 Posted by 파란크리스마스

출처 : XCode 스토리보드 사용시에 Segue 이용방법 3가지 | 아이군의 블로그

Page View Controller

   @IBAction func nextPageClicked(_ sender: UIButton) {
        
        let nextViewController = storyboard?.instantiateViewController(withIdentifier: "Page2") as! Page2ViewController
        
        self.present(nextViewController, animated : true)
    }

페이지 넘기기 효과

페이지 배열에 담기

    
    // lazy - 멤버가 생성되는 시점에는 메모리 할당하지 않음
    // 객체가 생성될때 초기화 함수 없이 정의만하고 객체내에서 호출시 메모리 할당
    lazy var vcArray:[UIViewController] = [self.loadVC(storyboardId: "page1VC"),
                                           self.loadVC(storyboardId: "page2VC"),
                                           self.loadVC(storyboardId: "page3VC")]
    
    // 스토리보드 ID로 ViewController 얻어오기
    func loadVC(storyboardId : String) -> UIViewController {
        return (storyboard?.instantiateViewController(withIdentifier:storyboardId))!
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        
        // laza 변수가 호출 되어 메모리 할당
        // static 으로 하지 않으면 객체가 만들기전에 self 함수를 호출 할 수 없지만
        // lazy 변수는 객체내에서 호출시 메모리 할당 - 미리 할당 하지 않음
        print(vcArray.count)
    }

페이지 이동 - 다음 페이지 지정

class PageViewController: UIPageViewController, UIPageViewControllerDataSource {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        guard let page1VC = vcArray.first else { return }
        self.setViewControllers([page1VC], direction: .forward, animated: true, completion: nil)
    }

    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        
        guard let curIndex = vcArray.index(of : viewController) else {
            return nil
        }
        
        let beforeIndex = curIndex - 1
        if beforeIndex < 0 {
            return vcArray.last
        } else {
            return vcArray[beforeIndex]
        }
    }
    
    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        
        guard let curIndex = vcArray.index(of : viewController) else {
            return nil
        }
        
        let beforeIndex = curIndex + 1
        if beforeIndex >= vcArray.count {
            return vcArray.first
        } else {
            return vcArray[beforeIndex]
        }
    }

페이지 넘기기 효과 제거하고 페이지 이동바 표시

    // Attributes inspector > Transition Style Scroll 경우 총페이지 표시
    public func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return vcArray.count
    }
    
    // Attributes inspector > Transition Style Scroll 경우 현재 페이지 표시
    public func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        return 0
    }

페이지 이동바 숨기기

   override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        for subView in view.subviews {
            // subView가 UIScrollView 이면, subView.frame을 전체 크기(UIScreen.main.bounds)로 한다 -> 페이지 넘기는 화면이 사라짐
            if subView is UIScrollView {
                subView.frame = UIScreen.main.bounds
            }
        }
    }

Modal 페이지 띄우기

        if let modalVC = storyboard?.instantiateViewController(withIdentifier: "modalVC") {
            modalVC.modalTransitionStyle = .flipHorizontal
            present(modalVC, animated: true, completion: {
                print("show modal complete")
            })
        }

Modal 페이지 닫기

dismiss(animated: true, completion: nil)

페이지 스텍을 전부 비우고 최상위 페이지로 이동

navigationController?.popToRootViewController(animated: true)

Modal 페이지 띄우기

   @IBAction func showPage4Clicked(_ sender: UIButton) {
        
        if let page4VC = storyboard?.instantiateViewController(withIdentifier: "page4VC") {
            navigationController?.pushViewController(page4VC, animated: true)
        }
    }
    
    @IBAction func showPage7Clicked(_ sender: UIButton) {
        
        let sb = UIStoryboard(name : "main3", bundle : nil)

        let page7VC = sb.instantiateViewController(withIdentifier: "page7VC")
        
        navigationController?.pushViewController(page7VC, animated: true)
        
    }
    
    @IBAction func showPage2Clicked(_ sender: UIButton) {
        
        
        navigationController?.popViewController(animated: true)
    }

    @IBAction func showPage3Clicked(_ sender: UIButton) {
        performSegue(withIdentifier: "showPage3Segue", sender: nil)
    }

댓글을 달아 주세요

Swift - UIImageView.animationImages

Programming/Swift 2017. 6. 17. 09:47 Posted by 파란크리스마스

출처 : ios - Swift - How to animate Images? - Stack Overflow

//
//  ViewController.swift
//  AniImage
//
//  Created by bluesanta on 2017. 6. 10..
//  Copyright © 2017년 bluesanta. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var indicatorImage: UIImageView!
    
    var imageArray = [UIImage]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        for i in 1...5 {
            imageArray.append(UIImage(named: String(format : "%02d.png", i))!)
        }
        
        indicatorImage.animationImages = imageArray
        indicatorImage.animationDuration = 0.7
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func startClicked(_ sender: UIButton) {
        indicatorImage.startAnimating()
    }
    
    @IBAction func stopClicked(_ sender: UIButton) {
        indicatorImage.stopAnimating()
    }
    

}


댓글을 달아 주세요