asklife

IT&Life

Month: 7月 2015 (page 1 of 2)

SwiftでiPhoneアプリ開発 – Part.10

本日もSwift Docsさんの写経です。

スクリーンショット 2015-07-22 23.21.02

//
//  ViewController.swift
//  Utillity001
//

import UIKit

class ViewController: UIViewController {
    
    //時間計測用の変数.
    var cnt : Float = 0
    
    //時間表示用のラベル.
    var myLabel : UILabel!
    
    override func viewDidLoad() {
        
        //ラベルを作る.
        myLabel = UILabel(frame: CGRectMake(0,0,200,50))
        myLabel.backgroundColor = UIColor.orangeColor()
        myLabel.layer.masksToBounds = true
        myLabel.layer.cornerRadius = 20.0
        myLabel.text = "Time:\(cnt)"
        myLabel.textColor = UIColor.whiteColor()
        myLabel.shadowColor = UIColor.grayColor()
        myLabel.textAlignment = NSTextAlignment.Center
        myLabel.layer.position = CGPoint(x: self.view.bounds.width/2,y: 200)
        self.view.backgroundColor = UIColor.cyanColor()
        self.view.addSubview(myLabel)
        
        //タイマーを作る.
        NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "onUpdate:", userInfo: nil, repeats: true)
    }
    
    //NSTimerIntervalで指定された秒数毎に呼び出されるメソッド.
    func onUpdate(timer : NSTimer){
        
        cnt += 0.1
        
        //桁数を指定して文字列を作る.
        let str = "Time:".stringByAppendingFormat("%.1f",cnt)
                
        myLabel.text = str
        
    }
    
}

ここで別の画面を開発して起動時の画面を変えたいため、
AppDelegate.swiftをいじります。

    
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        // ViewControllerを生成する.
        let viewController: ViewController = ViewController()
        // UIWindowを生成する.
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        
        // rootViewControllerにNatigationControllerを設定する.
        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()
        
        return true
    }

参考
https://sites.google.com/a/gcl……mawo-zuoru

SwiftでiPhoneアプリ開発 – Part.9

Xcodeで開発中に一つ前のバージョンに戻したい時

ターミナルでプロジェクトの位置まで移動し、以下コマンドを打ちます。

git checkout -f BRANCH

BRANCHは、コミットIDです。
githubの場合は、以下の画像のような英数字です。
スクリーンショット 2015-07-22 21.47.09

参考
http://www.hawk-a.com/exceptio……hives/2110

SwiftでiPhoneアプリ開発 – Part.8

GestureRecognizerというメソッドがあるので、それをいつものようにSwift Docsのコードを写経します。

UIKit043

GestureRecognizerはピンチや長押しなどを実現してくれるメソッドたちです。
以下の動画の後半(6分30秒くらい)に動いている様子があるので、参考まで

//
//  ViewController.swift
//  UIKit040
//

import UIKit

class ViewController: UIViewController {
    
    private var tapLabel: UILabel!
    private var pinchGestureLabel: UILabel!
    private var swipeLabel: UILabel!
    private var longPressLabel: UILabel!
    private var panLabel: UILabel!
    private var rotateLabel: UILabel!
    private var edgeLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 背景を赤色に.
        self.view.backgroundColor = UIColor.whiteColor()
        
        // タップを認識.
        let myTap = UITapGestureRecognizer(target: self, action: "tapGesture:")
        
        // ピンチを認識.
        let myPinchGesture = UIPinchGestureRecognizer(target: self, action: "pinchGesture:")
        
        // スワイプ認識.
        let mySwipe = UISwipeGestureRecognizer(target: self, action: "swipeGesture:")
        
        // スワイプ認識-2本指でスワイプ.
        mySwipe.numberOfTouchesRequired = 2
        
        // 長押しを認識.
        let myLongPressGesture = UILongPressGestureRecognizer(target: self, action: "longPressGesture:")
        
        // 長押し-最低2秒間は長押しする.
        myLongPressGesture.minimumPressDuration = 2.0
        
        // 長押し-指のズレは15pxまで.
        myLongPressGesture.allowableMovement = 150
        
        // パン認識.
        let myPan = UIPanGestureRecognizer(target: self, action: "panGesture:")
        
        // パン認識-3本指でパン.
        myPan.minimumNumberOfTouches = 3
        
        // 回転を認識.
        let myRotate = UIRotationGestureRecognizer(target: self, action: "rotateGesture:")
        
        // エッジを認識.
        let mySEdghePan = UIScreenEdgePanGestureRecognizer(target: self, action: "edgeGesture:")

        // エッジを認識-最低指3本で反応.
        mySEdghePan.minimumNumberOfTouches = 4
        
        // エッジを認識-左側.
        mySEdghePan.edges = UIRectEdge.Left
        
        // Viewに追加.
        self.view.addGestureRecognizer(myTap)
        self.view.addGestureRecognizer(myPinchGesture)
        self.view.addGestureRecognizer(mySwipe)
        self.view.addGestureRecognizer(myLongPressGesture)
        self.view.addGestureRecognizer(myPan)
        self.view.addGestureRecognizer(myRotate)
        self.view.addGestureRecognizer(mySEdghePan)
        
        let centerOfX = self.view.bounds.width / 2
        
        // Labelを作成.
        tapLabel = makeMyLabel("Tap", color: UIColor.redColor(), myX: centerOfX - 50 , myY: 100)
        pinchGestureLabel = makeMyLabel("Pinch", color: UIColor.greenColor(), myX: centerOfX + 50, myY: 100)
        swipeLabel = makeMyLabel("Swipe", color: UIColor.blueColor(), myX: centerOfX - 50, myY: 190)
        longPressLabel = makeMyLabel("Long", color: UIColor.orangeColor(), myX: centerOfX + 50, myY: 190)
        panLabel = makeMyLabel("Pan", color: UIColor.blackColor(), myX: centerOfX - 50, myY: 280)
        rotateLabel = makeMyLabel("Rotate", color: UIColor.cyanColor(), myX: centerOfX + 50, myY: 280)
        edgeLabel = makeMyLabel("Edge", color: UIColor.purpleColor(), myX: centerOfX - 50, myY: 370)
        
        // Viewに貼付ける.
        self.view.addSubview(tapLabel)
        self.view.addSubview(pinchGestureLabel)
        self.view.addSubview(swipeLabel)
        self.view.addSubview(longPressLabel)
        self.view.addSubview(panLabel)
        self.view.addSubview(rotateLabel)
        self.view.addSubview(edgeLabel)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
    /*
    タップイベント.
    */
    internal func tapGesture(sender: UITapGestureRecognizer){
        tapLabel.text = "\(sender.numberOfTouches())"
    }
    
    /*
    ピンチイベントの実装.
    */
    internal func pinchGesture(sender: UIPinchGestureRecognizer){
        let firstPoint = sender.scale
        let secondPoint = sender.velocity
        pinchGestureLabel.text = "\(Double(Int(firstPoint*100))/100)\n\(Double(Int(secondPoint*100))/100)"
    }
    
    /*
    スワイプイベント
    */
    internal func swipeGesture(sender: UISwipeGestureRecognizer){
        let touches = sender.numberOfTouches()
        swipeLabel.text = "\(touches)"
    }
    
    /*
    長押しイベント.
    */
    internal func longPressGesture(sender: UILongPressGestureRecognizer){
        // 指が離れたことを検知
        if(sender.state == UIGestureRecognizerState.Ended){
            longPressLabel.text = "On"
        }
    }
    
    /*
    パン.
    */
    internal func panGesture(sender: UIPanGestureRecognizer){
        panLabel.text = "\(sender.numberOfTouches())"
    }
    
    /*
    回転.
    */
    internal func rotateGesture(sender: UIRotationGestureRecognizer){
        
        let firstPoint = sender.rotation
        let secondPoint = sender.velocity
        rotateLabel.text = "\(Double(Int(firstPoint*100))/100)\n\(Double(Int(secondPoint*100))/100)"
    }
    
    /*
    エッジ.
    */
    internal func edgeGesture(sender: UIScreenEdgePanGestureRecognizer){
        let touches = sender.numberOfTouches()
        swipeLabel.text = "\(touches)"
    }
    
    internal func makeMyLabel(title: NSString, color: UIColor, myX: CGFloat, myY: CGFloat) -> UILabel{
        let myLabel: UILabel = UILabel()
        myLabel.frame = CGRectMake(0,0,80,80)
        myLabel.backgroundColor = color
        myLabel.textColor = UIColor.whiteColor()
        myLabel.layer.masksToBounds = true
        myLabel.text = title as String
        myLabel.textAlignment = NSTextAlignment.Center
        myLabel.layer.cornerRadius = 40.0
        myLabel.layer.position = CGPoint(x: myX, y: myY)
        myLabel.numberOfLines = 2
        return myLabel
    }
    
}

ピンチの発生のさせ方はOptionキーを押したマウスを動かすとできます。

その他iOSシュミレータの動かし方はこちらが参考になります。
http://qiita.com/hirayaCM/item……7d513e4923

参考
https://sites.google.com/a/gcl……wo-ren-shi

SwiftでiPhoneアプリ開発 – Part.7

UIKit047_001UIKit047_002

Swift DocsのUIScrollViewで画面を作りました。

ポイントは以下二つ。
1.scrollViewDidScroll
スクロールをトリガーにfunctionを動作させるはずなので、ここを拡張性持つようにすべきです。

2.pageSize
サンプルだと、固定長ですが可変長で利用することが多いはずなので以下のようにして、セットできるようにしました。

    struct scrollPages{
        static var pageSize = 1
    }

実装はまんま、SwiftDocsです。

//
//  ViewController.swift
//  UIKit046
//

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {
    
    // UIPageControl.
    var pageControl: UIPageControl!
    // UIScrillView.
    var scrollViewHeader: UIScrollView!
    var scrollViewMain: UIScrollView!
    // ページ番号.
    let pageSize = 10
    
    override func viewDidLoad() {
        
        // 画面サイズの取得.
        let width = self.view.frame.maxX, height = self.view.frame.maxY
        
        // ScrollViewHeaderの設定.
        scrollViewHeader = UIScrollView(frame: self.view.frame)
        scrollViewHeader.showsHorizontalScrollIndicator = false
        scrollViewHeader.showsVerticalScrollIndicator = false
        scrollViewHeader.pagingEnabled = true
        scrollViewHeader.delegate = self
        scrollViewHeader.contentSize = CGSizeMake(CGFloat(pageSize) * width, 0)
        self.view.addSubview(scrollViewHeader)
        
        // ScrollViewMainの設定.
        scrollViewMain = UIScrollView(frame: self.view.frame)
        scrollViewMain.showsHorizontalScrollIndicator = false
        scrollViewMain.showsVerticalScrollIndicator = false
        scrollViewMain.pagingEnabled = true
        scrollViewMain.delegate = self
        scrollViewMain.contentSize = CGSizeMake(CGFloat(pageSize) * width, 0)
        self.view.addSubview(scrollViewMain)

        // ScrollView1に貼付けるLabelの生成.
        for var i = 0; i < pageSize; i++ {
            
            //ページごとに異なるラベルを表示.
            let myLabel:UILabel = UILabel(frame: CGRectMake(CGFloat(i) * width + width/2 - 40, height/2 - 40, 80, 80))
            myLabel.backgroundColor = UIColor.blackColor()
            myLabel.textColor = UIColor.whiteColor()
            myLabel.textAlignment = NSTextAlignment.Center
            myLabel.layer.masksToBounds = true
            myLabel.text = "Page\(i)"
            myLabel.font = UIFont.systemFontOfSize(UIFont.smallSystemFontSize())
            myLabel.layer.cornerRadius = 40.0
            
            scrollViewMain.addSubview(myLabel)
        }
        
        // ScrollView2に貼付ける Labelの生成.
        for var i = 0; i < pageSize; i++ {
            
            //ページごとに異なるラベルを表示.
            let myLabel:UILabel = UILabel(frame: CGRectMake(CGFloat(i) * width/4 + width/2 - 40, 50, 80, 60))
            myLabel.backgroundColor = UIColor.redColor()
            myLabel.textColor = UIColor.whiteColor()
            myLabel.textAlignment = NSTextAlignment.Center
            myLabel.layer.masksToBounds = true
            myLabel.text = "Page\(i)"
            myLabel.font = UIFont.systemFontOfSize(UIFont.smallSystemFontSize())
            myLabel.layer.cornerRadius = 30.0
            
            scrollViewHeader.addSubview(myLabel)
        }
        
        // PageControlを作成.
        pageControl = UIPageControl(frame: CGRectMake(0, self.view.frame.maxY - 50, width, 50))
        pageControl.backgroundColor = UIColor.lightGrayColor()
        
        // PageControlするページ数を設定.
        pageControl.numberOfPages = pageSize
        
        // 現在ページを設定.
        pageControl.currentPage = 0
        pageControl.userInteractionEnabled = false
        
        self.view.addSubview(pageControl)
    }
    
    /*
     ScrollViewが移動した際に呼ばれる.
    */
    func scrollViewDidScroll(scrollView: UIScrollView) {
        if scrollView == scrollViewMain {
            scrollViewHeader.contentOffset.x = scrollViewMain.contentOffset.x/4
        }
    }
    
    /*
     移動が完了したら呼ばれる.
    */
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        
        // スクロール数が1ページ分になったら.
        if fmod(scrollViewMain.contentOffset.x, scrollViewMain.frame.maxX) == 0 {
            // ページの場所を切り替える.
            pageControl.currentPage = Int(scrollViewMain.contentOffset.x / scrollViewMain.frame.maxX)
        }
    }
}

また、Swiftのjsonパーサーで良いのがありましたのでご紹介します。
https://github.com/dankogai/sw……json.swift

参考
https://sites.google.com/a/gcl……g-qisaseru

SwiftでiPhoneアプリ開発 – Part.6

スクリーンショット 2015-06-30 21.13.30

位置情報を取得するアプリを作ります。

Xcodeをいじるのでポイントは以下
1.Core Location フレームワークを追加

スクリーンショット 2015-06-30 21.17.17

2.info.plistにkey:NSLocation… value:任意の文言 を追加する。
・アプリ使用中のみ許可: NSLocationWhenInUseUsageDescription
・アプリ使用中以外も常に許可: NSLocationAlwaysUsageDescription

スクリーンショット 2015-06-30 21.18.35

スクリーンショット 2015-06-30 21.18.23

3.実装する
実装サンプルはSwift Docsまんまです。

//
//  ViewController.swift
//  CoreLocation001
//

import UIKit
import CoreLocation

class ViewController: UIViewController , CLLocationManagerDelegate{
    
    var myLocationManager:CLLocationManager!
    
    // 緯度表示用のラベル.
    var myLatitudeLabel:UILabel!
    
    // 経度表示用のラベル.
    var myLongitudeLabel:UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ボタンの生成.
        let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        myButton.backgroundColor = UIColor.orangeColor()
        myButton.layer.masksToBounds = true
        myButton.setTitle("Get", forState: .Normal)
        myButton.layer.cornerRadius = 50.0
        myButton.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2)
        myButton.addTarget(self, action: "onClickMyButton:", forControlEvents: .TouchUpInside)
        
        // 緯度表示用のラベルを生成.
        myLatitudeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 30))
        myLatitudeLabel.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2+100)
        
        // 軽度表示用のラベルを生成.
        myLongitudeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 30))
        myLongitudeLabel.layer.position = CGPoint(x: self.view.bounds.width/2, y:self.view.bounds.height/2+130)
        
        
        // 現在地の取得.
        myLocationManager = CLLocationManager()
        
        myLocationManager.delegate = self
        
        // セキュリティ認証のステータスを取得.
        let status = CLLocationManager.authorizationStatus()
        
        // まだ認証が得られていない場合は、認証ダイアログを表示.
        if(status == CLAuthorizationStatus.NotDetermined) {
            println("didChangeAuthorizationStatus:\(status)");
            // まだ承認が得られていない場合は、認証ダイアログを表示.
            self.myLocationManager.requestAlwaysAuthorization()
        }
        
        // 取得精度の設定.
        myLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        // 取得頻度の設定.
        myLocationManager.distanceFilter = 100
        
        self.view.addSubview(myButton)
    }
    
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        
        println("didChangeAuthorizationStatus");
        
        // 認証のステータスをログで表示.
        var statusStr = "";
        switch (status) {
        case .NotDetermined:
            statusStr = "NotDetermined"
        case .Restricted:
            statusStr = "Restricted"
        case .Denied:
            statusStr = "Denied"
        case .AuthorizedAlways:
            statusStr = "AuthorizedAlways"
        case .AuthorizedWhenInUse:
            statusStr = "AuthorizedWhenInUse"
        }
        println(" CLAuthorizationStatus: \(statusStr)")
    }
    
    // ボタンイベントのセット.
    func onClickMyButton(sender: UIButton){
        // 現在位置の取得を開始.
        myLocationManager.startUpdatingLocation()
    }
    
    // 位置情報取得に成功したときに呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!){
        
        // 緯度・経度の表示.
        myLatitudeLabel.text = "緯度:\(manager.location.coordinate.latitude)"
        myLatitudeLabel.textAlignment = NSTextAlignment.Center
        
        myLongitudeLabel.text = "経度:\(manager.location.coordinate.longitude)"
        myLongitudeLabel.textAlignment = NSTextAlignment.Center
        
        
        self.view.addSubview(myLatitudeLabel)
        self.view.addSubview(myLongitudeLabel)
        
    }
    
    // 位置情報取得に失敗した時に呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!){
        print("error")
    }
    
}

4.iOSシュミレータで動かす時には、Debugモードで位置情報を付与してあげる。

シュミレータ起動->Debug->Simular location

スクリーンショット 2015-06-30 21.23.43

ここで先ほどinfo.plistに入れたvalueの文言が表示されてますね。
スクリーンショット 2015-06-30 21.28.42

Allowを選んで、位置情報が表示されました。
スクリーンショット 2015-06-30 21.13.30

5.シュミレータのAllow情報などを消すには
iOS Simulator -> Reset Content and Settings

スクリーンショット 2015-06-30 21.28.03

 

6.位置情報の取得タイミング!

めっちゃはまりました。位置情報の取得タイミングは非同期です。
locationManagerが動くと、位置情報は取得されています。(おそらく)

そのため、位置情報を取得して、fooサーバにlat/lngを付与して情報を取得するような処理を書きたい時は
locationManagerの中で、位置情報が取得できた後に、記述する必要があります。

こう書くと当たり前ですが、結構な時間詰まってしまいました。。。

//
//  ViewController.swift
//

import UIKit
import CoreLocation

class ViewController: UIViewController,CLLocationManagerDelegate {
    
    
    var myLocationManager:CLLocationManager!
    
    struct location{
        static var lat = ""
        static var lng = ""
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Geo Request
        self.getGeo()

    }
    
    func getGeo(){
        // 現在地の取得.
        myLocationManager = CLLocationManager()
        
        myLocationManager.delegate = self
        // セキュリティ認証のステータスを取得.
        let status = CLLocationManager.authorizationStatus()
        // まだ認証が得られていない場合は、認証ダイアログを表示.
        if(status == CLAuthorizationStatus.NotDetermined) {
            println("didChangeAuthorizationStatus:\(status)");
            // まだ承認が得られていない場合は、認証ダイアログを表示.
            self.myLocationManager.requestAlwaysAuthorization()
        }
        // 取得精度の設定.
        myLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        // 取得頻度の設定.
        myLocationManager.distanceFilter = 100

        // 現在位置の取得を開始.
        myLocationManager.startUpdatingLocation()
    }
    
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        
        println("didChangeAuthorizationStatus");
        
        // 認証のステータスをログで表示.
        var statusStr = "";
        switch (status) {
        case .NotDetermined:
            statusStr = "NotDetermined"
        case .Restricted:
            statusStr = "Restricted"
        case .Denied:
            statusStr = "Denied"
        case .AuthorizedAlways:
            statusStr = "AuthorizedAlways"
        case .AuthorizedWhenInUse:
            statusStr = "AuthorizedWhenInUse"
        }
        println(" CLAuthorizationStatus: \(statusStr)")
    }
    
    // 位置情報取得に成功したときに呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didUpdateLocations locations: [AnyObject]!){
        
        location.lat = String(stringInterpolationSegment: manager.location.coordinate.latitude)
        location.lng = String(stringInterpolationSegment: manager.location.coordinate.longitude)
        
        println(location.lat)
        println(location.lng)
        
        // HTTP Request ★★★
        self.reqHttp()
        
    }
    
    // 位置情報取得に失敗した時に呼び出されるデリゲート.
    func locationManager(manager: CLLocationManager!,didFailWithError error: NSError!){
        print("error")
    }
    
    
    func reqHttp(){
        // 通信先のURLを生成.
        var myUrl:NSURL = NSURL(string:"http://foo/bar?lat=" + String(location.lat) + "&lng="+String(location.lng)+"/")!
        
        // リクエストを生成.
        var myRequest:NSURLRequest  = NSURLRequest(URL: myUrl)
        // 送信処理を始める.
        NSURLConnection.sendAsynchronousRequest(myRequest, queue: NSOperationQueue.mainQueue(), completionHandler: self.getHttp)
        println(myUrl)
    }
    
    func getHttp(res:NSURLResponse?,data:NSData?,error:NSError?){
        // NSData -> NSDictionary
        let json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments, error: nil) as! NSDictionary
    }
        
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


}

 

以上で、位置情報の取得方法でした!

参考
https://sites.google.com/a/gcl……hino-qu-de
http://dev.classmethod.jp/refe……ification/
http://swift-studying.com/blog……ft/?p=1078
http://shirokai.hatenablog.com……/swift-gps
http://www.hnyssh.net/?p=577

Older posts

© 2017 asklife

Theme by Anders NorenUp ↑