27
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Swift] 自作UILabelにDelegateでタッチイベントをつける

Last updated at Posted at 2014-10-22

UILabelを継承した自作のクラスに、delegateとprotocolを追加し
ボタンを押して離したときにdelegateメソッドで処理が出来るラベルのサンプルを作っていきます。

まずは自作ラベルを作ります。
新規ファイルからCocoa Touch Classを選択します。
クラス名は「CustomLabel」に、「Subclass of:」はUILabelを入力してUILabelを親クラスにします。(Language:はSwiftで!)。

次にstoryboardを開いてラベルを配置します。
Xcodeの右下の一覧から、UILabelをViewにドラックして適当な位置に配置してください。
(ラベルは大きめに作って、背景色をつけると分かりやすくなります)
右側のUtilityエリアから、「show the identity inspector」を選び、
「Custom Class」のClassのフィールドに先ほど作成した「CustomLabel」の名前を入力します(cと入力すれば予測表示してくれると思います。)

そしたら後は通常通りに配置したLabelの要素をcontrolキーを押しながらコードまで線を引っ張って配置します。
(名前はmyLabelで作成しました。)

CustomLabel.swift

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var myLabel: CustomLabel!

    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.
    }


}

次に、自作するラベルのCustomLabelを実装していきます。(以下をコピペでもOKです)

CustomLabel.swift

import UIKit

protocol CustomLabelDelegate: class {
    func touchUpInside(customLabel: CustomLabel)
}

class CustomLabel: UILabel {

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.userInteractionEnabled = true
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        self.textColor = UIColor.lightGrayColor()
    }
    
    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        self.textColor = UIColor.blackColor()
        
        let touch = touches.anyObject() as UITouch
        let point = touch.locationInView(self)
        if CGRectContainsPoint(self.bounds, point) {
            self.touchUpInside()
        }
    }
    
    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        let touch = touches.anyObject() as UITouch
        let point = touch.locationInView(self)
        
        if CGRectContainsPoint(self.bounds, point) {
            self.textColor = UIColor.lightGrayColor()
        }else{
            self.textColor = UIColor.blackColor()
        }
    }

    override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {
        self.textColor = UIColor.blackColor()
    }
    
    // MARK: - delegate
    weak var delegate: CustomLabelDelegate?
    func touchUpInside() {
        delegate?.touchUpInside(self)
    }

}

ラベルをタップしたときの処理はUITouchを使用しました。
コードの最初の方にprotocolを宣言し、コードの最後の方にデリゲートの処理を書きました。
肝は、override func touchesEnded(touches: NSSet, withEvent event: UIEvent) メソッドで
ラベルをタッチして、離した際に離したポイントがそのラベルの上だったときのみに処理をするようにしています。
(ついでに色も変わるようにしました。)

CustomLabelの実装は以上なので、次はViewController.swiftにボタンを押したとき(正確には押して、離したとき)のデリゲート処理を実装します。

ViewController.swift

import UIKit

class ViewController: UIViewController, CustomLabelDelegate {
    
    @IBOutlet weak var myLabel: CustomLabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        myLabel.delegate = self
        //myLabel.delegate(self) <- エラーになったので修正しました。
        
    }

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

    func touchUpInside(customLabel: CustomLabel) {
        println("touchUpInside!")
    }
}

クラスの宣言(class ViewController: UIViewController)の右に CustomLabelDelegateを追加します。
追加するとエラーが出るので、touchUpInside()メソッドを追加してください。
あとは、「myLabel.delegate(self)」を追加してやればデリゲートメソッドが使えるようになります!

これで完成です。
ラベルをタッブした状態で移動し、ラベルの領域を外れた時の処理も override func touchesMoved(touches: NSSet, withEvent event: UIEvent) メソッドで実装したのでUIButtonらしい動きが再現出来たと思います。
応用すれば色んなタッチイベントが実装出来ると思います。

※コメントでご指摘頂いた箇所と「myLabel.delegate = self」がエラーになっていたので修正しました。ご指摘ありがとうございましたm(_ _)m

27
23
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?