iOS Tips集

こんにちは。エンジニアの志村です。
Cluexでは7月に「ままのて」という、妊娠中〜育児中まで医師監修のQ&Aやメッセージをお届けするアプリをローンチしました。

appsto.re

上記に伴いNativeアプリ専門のチームが出来ました。
現在、私含め3人でままのての改善やAndroid版の実装を行っております。
社内では2ヶ月に1回のLT大会や毎日終業前に行う豆知識の時間(軽いTips等を1人2〜3分程度で話す時間)を利用して、積極的に知識の共有や新しい知識を習得するようにしております。

今回はその中で出た知識をまとめたものを文章化しました。(このシリーズ定期的に出したいなぁ)

bounds

スクリーンからみて、Viewのサイズや位置などを保持するプロパティ。

class HogeViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // スクリーン上のtableViewのwidthを取得
        var width = self.tableView.bounds.width
        // スクリーン上のtableViewのheightを取得
        var height = self.tableView.bounds.height
    }
}

by 井戸田

IPアドレスの取得

1. getifaddrs(&ifaddr)
2. if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING)
3. freeifaddrs(ifaddr)

ポイント

  1. ifaddr変数のポインタを渡して、ifaddrに取得した内容を格納する。
  2. ビットフラグで状態確認している。flagsがUP, RUNNINGの時&&LOOPBACKではない時を指す。
  3. getifaddrs関数の中でifaddrにメモリ確保しているので、メモリ解放する為にifaddrを渡す。

参照

get an iPhone's device name and get Ip address in swift 3

by 高島

addSubview, addSublayerをした時にきちんとremoveしよう

addSubview, addSublayerをUIViewに対して行った場合、追加されたUIViewやCALayerは残り続ける。
もし、UITableViewのcellForRowAt等で当該処理を行った場合、スクロールの度にUIViewやCALayerが追加され、メモリを圧迫するだけでは無く、表示そのものが崩れる場合があるので注意。
なので基本的にaddSubviewやaddSublayerを使用する場合は、事前にremoveFromSuperview, removeFromSuperlayerを行うべきである。

    func addCornerRadius(corners: UIRectCorner, radius: CGFloat) {
        if let oldMaskLayer = self.layer.value(forKey: "maskLayer") as? CAShapeLayer {
            oldMaskLayer.removeFromSuperlayer()
        }

        let maskPath = UIBezierPath(
            roundedRect: self.bounds,
            byRoundingCorners: corners,
            cornerRadii: CGSize(width: radius, height: radius)
        )
        let maskLayer = CAShapeLayer()
        self.layer.setValue(maskLayer, forKey: "maskLayer")

        maskLayer.frame = self.bounds
        maskLayer.path  = maskPath.cgPath
        self.layer.mask = maskLayer
    }

上記コードはUIViewに対して特定のcornerのみにradiusを付ける関数である。
上記コードで、もしif let oldMaskLayer〜が存在しない場合 && tableView.reloadData()を行い、heightが再計算される場合、前回使用していた高さでCAShapeLayerが描画されており、2重に線が描画される恐れがある。

by 志村

iOS9におけるremoveObserverの扱い

iOS9より、NotificationCenterはaddObserverで受け取ったオブザーバをweakで参照するようになる。
なので、明示的にremoveFromObserverをする必要がなくなった。

// Before iOS9
override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: "update:", name: MyNotification, object: nil)
}

deinit {
    NotificationCenter.default.removeObserver(self, selector: "update:", name: MyNotification, object: nil)
}

//  iOS9
override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: "update:", name: MyNotification, object: nil)
}

deinit {
}

参考

swift - NSNotificationCenterのremoveObserverについて - スタック・オーバーフロー

by 志村

以上になります。 このような感じで毎日知識を共有するようにしております。 次回からAndroid版も出来ると良いなぁ…

We’re hiring!!

弊社ではWeb / ネイティブアプリエンジニアを募集しております。
ご興味がありましたらお気軽にご連絡下さいませ!
エンジニアの方、ぜひ情報交換しましょう!

www.wantedly.com

www.wantedly.com