iOSエンジニアのマイペースなブログ

iOSエンジニアのマイペースな私が勉強がてら書いています。

I have implemented Class LocalAuthentication that provide facilities for requesting authentication. We can use it on only device having touch ID.I made it in singleton pattern to be convenient.We can even use it on Air2.

import LocalAuthentication

class LocalAuthMgr: NSObject {
    
    let myContext = LAContext()
    let myLocalizedReasonString = "testrun"
    
    var authError: NSError? = nil
    
    
    static let shared:LocalAuthMgr = LocalAuthMgr()
    private override init() {}
    
    func auth() {
    
        if #available(iOS 8.0, OSX 10.12, *) {
        
            if myContext.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &authError) {
                myContext.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedReasonString) { (success, evaluateError) in
                    if (success) {
                        
                        print("suc")
                        
                    } else {
                        
                        print("er1")
                        
                    }
                    
                }
                
            } else {
                
                print("er2")
                
            }
        
        } else {
            
            print("er3")
        }
        
    }
    
}

If you execute on Air2,you can get the following error:Code=-7 "No fingers are enrolled with Touch ID.".
If you cancel on iPhone7,you can get the following errpr:Code=-2 "Canceled by user.".
If you have fail three times,you can get the following error:Code=-1 "Application retry limit exceeded.". In the case,you will not be able to use Touch Id on the device unless you enter your password.
If you choice "input password",you can get the following error:Code=-3 "Fallback authentication mechanism selected.".

You can set the duration for which Touch ID authentication reuse is allowable.

LAContext class provides property of "touchIDAuthenticationAllowableReuseDuration". If you set the specified time interval to this property,the authentication for the receiver succeed automatically. The default value is 0 and the maximum value is 300( this is constant).

これを

201707011

こうします。

201707012

回転後に配置したいx座標、y座標から逆算して、回転前のx座標、y座標を決定しておく必要があります。下記が回転前のx座標、y座標を算出するための計算式です。

201707013

ソースはこんな感じ

override func viewDidLoad() {
        super.viewDidLoad()
        
        let width = 100
        let height = 50
        let afterX = 200
        let afterY = 200
        var beforeX = 0
        var beforeY = 0
        
        //この計算式が大事
        beforeX = afterX - (width - height) / 2
        beforeY = afterY - (height - width) / 2 - width

        let label: UILabel = UILabel(frame: CGRect(x:beforeX,y:beforeY,width:width,height:height))
        label.backgroundColor = UIColor.orange
        label.text = "移動するラベル"
        label.font = UIFont(name: "HiraKakuProN-W6", size: 8.5)
        label.textColor = UIColor.black
        self.view.addSubview(label)
        
        print(label.frame)

        print(label.bounds)
        
        label.transform = label.transform.rotated(by: CGFloat(Double.pi)/(-2))

        print(label.frame)
        
        print(label.bounds)

        
        let label2: UILabel = UILabel(frame: CGRect(x:afterX,y:afterY,width:width,height:height))
        label2.backgroundColor = UIColor.blue
        label2.text = "ここにもってくる"
        label2.font = UIFont(name: "HiraKakuProN-W6", size: 8.5)
        label2.textColor = UIColor.black
        self.view.addSubview(label2)
        
    }

swift3で時計を作りました。メイン機能ではないけどダッシュボード的な画面の場合おまけ機能で実装されることもあるかと思います。下記のようなフォーマットでTimerを使用して現在時刻が表示されるようにします。

32

storyboardでUIを作成しましょう。UILabelは1文字づつ作成してください。なぜかというと、1個のUILabelで時間を表現すると、時間の変化によって数字の位置がずれて見えてしまうからです。

32

次に、現在日時をAM/PM表記で返してくれるファンクションを作成します。

func getNowTimeString() -> String {
        
        // 日付のフォーマットを指定
        // AM/PM表記をここで指定する
        let formatter = DateFormatter()
        formatter.dateFormat = "hh:mm a"
        formatter.amSymbol = "AM"
        formatter.pmSymbol = "PM"
        let now = Date()
        // 現在の日時をAM/PM表記のstring型で返却する
        return formatter.string(from: now)
        
    }

次に現在日時をUILabelにセットします。今回はアニメーションするようにしました。先ほど取得した現在日時を分解します。

func showTime() {
        
        // 現在日時の取得
        let now = getNowTimeString()
        
        // 現在時間の2桁名をUILabelに表示
        UIView.transition(with: self.time1,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time1.text = now.substring(to: now.index(now.startIndex, offsetBy: 1))
            }, completion: nil)
        
        // 現在時間の1桁をUILabelに表示
        UIView.transition(with: self.time2,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time2.text = now.substring(with: now.index(now.startIndex, offsetBy: 1)..< now.index(now.endIndex, offsetBy: -6))
            }, completion: nil)

        // 現在時間の分の2桁をUILabelに表示
        UIView.transition(with: self.time3,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time3.text = now.substring(with: now.index(now.startIndex, offsetBy: 3)..< now.index(now.endIndex, offsetBy: -4))
            }, completion: nil)

        // 現在時間の分の1桁をUILabelに表示
        UIView.transition(with: self.time4,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time4.text = now.substring(with: now.index(now.startIndex, offsetBy: 4)..< now.index(now.endIndex, offsetBy: -3))
            }, completion: nil)
        
        // 現在時間のAM/PMをUILabelに表示
        UIView.transition(with: self.ampm,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.ampm.text = now.substring(with: now.index(now.startIndex, offsetBy: 6)..< now.index(now.endIndex, offsetBy: 0))
            }, completion: nil)
        
    }

全ソースはこちら。使い回しできますねー

import UIKit

class ViewController: UIViewController {

    // UILabelを日付ごとに作成する
    // またam、pmを表示するためのUILabelを作成する
    @IBOutlet weak var ampm: UILabel!
    @IBOutlet weak var time1: UILabel!
    @IBOutlet weak var time2: UILabel!
    @IBOutlet weak var time3: UILabel!
    @IBOutlet weak var time4: UILabel!
    
    // timer用のプロパティを作成する
    var timeShowTimer: Timer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // timerの設定
        // 1秒ごとにself.showTimeを起動する
        timeShowTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.showTime), userInfo: nil, repeats: true)
        // timer起動
        timeShowTimer.fire()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)
        
        // timer終了
        timeShowTimer.invalidate()
    }

    func getNowTimeString() -> String {
        
        // 日付のフォーマットを指定
        // AM/PM表記をここで指定する
        let formatter = DateFormatter()
        formatter.dateFormat = "hh:mm a"
        formatter.amSymbol = "AM"
        formatter.pmSymbol = "PM"
        let now = Date()
        // 現在の日時をAM/PM表記のstring型で返却する
        return formatter.string(from: now)
        
    }

    func showTime() {
        
        // 現在日時の取得
        let now = getNowTimeString()
        
        // 現在時間の2桁名をUILabelに表示
        UIView.transition(with: self.time1,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time1.text = now.substring(to: now.index(now.startIndex, offsetBy: 1))
            }, completion: nil)
        
        // 現在時間の1桁をUILabelに表示
        UIView.transition(with: self.time2,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time2.text = now.substring(with: now.index(now.startIndex, offsetBy: 1)..<now.index(now.endIndex, offsetBy: -6))
            }, completion: nil)

        // 現在時間の分の2桁をUILabelに表示
        UIView.transition(with: self.time3,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time3.text = now.substring(with: now.index(now.startIndex, offsetBy: 3)..<now.index(now.endIndex, offsetBy: -4))
            }, completion: nil)

        // 現在時間の分の1桁をUILabelに表示
        UIView.transition(with: self.time4,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.time4.text = now.substring(with: now.index(now.startIndex, offsetBy: 4)..<now.index(now.endIndex, offsetBy: -3))
            }, completion: nil)
        
        // 現在時間のAM/PMをUILabelに表示
        UIView.transition(with: self.ampm,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.ampm.text = now.substring(with: now.index(now.startIndex, offsetBy: 6)..<now.index(now.endIndex, offsetBy: 0))
            }, completion: nil)
        
    }

}

このページのトップヘ