カテゴリー
SugiBlog ホームページ制作・システム開発|大阪

UIViewのアニメーション

今回はUIViewやUIButtonをアニメーションさせる方法をご紹介します。

まずはアニメーションさせる適当なViewを作成します。

let sampleView = UIView()

sampleView.frame.size = CGSize(width: 120, height: 120)
sampleView.center = CGPoint(x: 60, y: 60)
sampleView.backgroundColor = UIColor.white
sampleView.layer.borderColor = UIColor.cyan.cgColor
sampleView.layer.borderWidth = 2

view.addSubview(sampleView)

作成したViewをアニメーションさせるにはUIView.animateメソッドを使用します。
ここでは大きさを変更してみましょう。
中心点も設定しているのは、大きさを変更すると左上を起点に大きさが変わってしまうためです。

UIView.animate(withDuration: 0.5, animations: {
    self.sampleView.frame.size = CGSize(width: 80, height: 80)
    self.sampleView.center = CGPoint(x: 60, y: 60)
}, completion: { Void in
    // アニメーション完了時の処理を記述します
})

次に、大きさと角丸の半径をアニメーションで変更してみたいと思います。
サンプルとして、標準カメラアプリの動画撮影ボタンのようなボタンを作成してみましょう。
実際の撮影処理はしていません。

まずは必要な宣言

let shutterView = UIView()
let shutterButton = UIButton()
var isRecording: Bool = false

Viewを作成するメソッドを作成します。

func makeShutterView() {
    shutterView.frame.size = CGSize(width: 74, height: 74)
    shutterView.center = CGPoint(x: 45, y: 45)

    let shutterCircle = UIView()
    shutterCircle.frame.size = CGSize(width: 76, height: 76)
    shutterCircle.center = CGPoint(x: 45, y: 45)
    shutterCircle.layer.borderColor = UIColor.white.cgColor
    shutterCircle.layer.borderWidth = 4
    shutterCircle.layer.cornerRadius = 38.0
    shutterView.addSubview(shutterCircle)

    shutterButton.frame.size = CGSize(width: 60, height: 60)
    shutterButton.center = CGPoint(x: 45, y: 45)
    shutterButton.backgroundColor = UIColor.red
    shutterButton.layer.cornerRadius = 30.0
    shutterButton.addTarget(self, action: #selector(onClickRecordingButton), for: .touchUpInside)
    shutterView.addSubview(shutterButton)

    view.addSubview(shutterView)
}

続きを読む…»

1,223 views

Ad Hoc配布する.ipaファイル作成までのプロセスメモ

Apple Developer Programにアクセスし、アカウントをクリックしてサインイン
https://developer.apple.com/programs/jp/

左メニューの「Certificates, IDs & Profiles」を選択

「Certificates」の「+」をクリックして証明書を作成
その際に必要なもの:.certSigningRequestファイル

.certSigningRequestファイルの作成方法
キーチェーンアプリを起動
[キーチェーンアクセス]-[証明書アシスタント]-[認証局に証明書を要求…]を
選択して必要事項を記入して作成

「Provisioning Profiles」の「Distribution」のプロファイルを「Ad Hoc」で作成
作成が完了するとDeveloper Provisioning Profile」ファイルをダウンロードできる
ダウンロード後、該当ファイルをダブルクリックするとXcodeに取り込まれる

「Identifiers」の「App IDs」でApp IDを登録

.ipaファイルのエクスポートはXcodeの[Product]-[Archive]から行う

参考URL:
http://akiyoko.hatenablog.jp/entry/2013/11/28/224536
https://i-app-tec.com/ios/ios-app-ids.html
http://joyplot.com/documents/2016/10/29/ios-app-id-manually/
https://i-app-tec.com/ios/ad-hoc.html
http://dev.classmethod.jp/smartphone/testflight-whole-process-2016-spring-01/

3,986 views

UISearchControllerの警告

UISearchControllerを使っていると、ViewControllerが破棄されるタイミングで以下のような警告が出てきました。

[Warning] Attempting to load the view of a view controller while it is deallocationg is not allowed and may result in undefined behavior (<UISearchController: ...>)

どうやらViewControllerが破棄されるタイミングでSearchControllerも破棄してやらないといけないようです。

以下のコードを追加したら解決しました。

deinit {
    searchController.view.removeFromSuperview()
}

また、実際に検索をして別画面に遷移した際に、UISearchControllerの表示が残ったままになる問題が発生しました。
キャンセルをタップすれば消すことができますが、それでは気持ちが悪いので解決させたい。
解決方法は遷移元のUIViewControllerのviewDidonLoadに以下の1行を追加するだけです。

definesPresentationContext = true

私の場合、原因はUINavigationControllerを使っていたことでした。

こちらで詳しく解説されています。
参考URL: http://qiita.com/color_box/items/d13b04a88587088019af

Xcode: 8.3.2
Swift: 3.1
OS: Sierra 10.12

910 views

UITableView スワイプでセルを削除する

簡単に実装できるので楽ですね。

UITableViewをOutlet接続しておきます。

@IBOutlet weak var table: UITableView!

削除処理の実装

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        table.deleteRows(at: [indexPath], with: .fade)
    }
}

Xcode: 8.3.2
Swift: 3.1
OS: Sierra 10.12

1,884 views

ContainerView 親ビューから子ビューを操作したい

iOSのアプリ開発でコンテナビュー(ContainerView)が便利なので使ってみました。
その際、子ビューから別の子ビューのメソッドを実行して操作したい、ということがありました。

やってみるとそこまで難しくなかったので、簡単にご紹介したいと思います。

パターンとして、親ビューから子ビュー、子ビューから親ビュー、子ビューから別の子ビューの3通りをご紹介します。

親ビューから子ビュー

子ビュー側

class ChildController: UIViewController {
    func test() {
        //code
    }
}

親ビュー側

let targetVC = childViewControllers[0] as! ChildController
targetVC.test()

子ビューから親ビュー

親ビュー側

class ParentController: UIViewController {
    func test() {
        //code
    }
}

子ビュー側

let parentVC = self.parent as! ParentController
parentVC.test()

続きを読む…»

5,653 views

スクリーンショットを添付してメール送信

MFMailComposeViewControllerを使ってメールを作成します。

まずはMessageUIをインポートします。

import MessageUI

デリゲートを追加します。

class sample: UIViewController, MFMailComposeViewControllerDelegate {
func mail(subject: String, mailbody: String) {
    let composeVC = MFMailComposeViewController()
    composeVC.mailComposeDelegate = self

    composeVC.setToRecipients(["送信先メールアドレス"])

    composeVC.setSubject(subject)

    composeVC.setMessageBody(mailbody, isHTML: false)

    let layer = UIApplication.shared.keyWindow?.layer
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions((layer?.frame.size)!, false, scale)

    layer?.render(in: UIGraphicsGetCurrentContext()!)
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    let image = UIImageJPEGRepresentation(screenshot!, 1.0)
    UIGraphicsEndImageContext()

    composeVC.addAttachmentData(image!, mimeType: "image/png", fileName: "screenshot.png")

    self.present(composeVC, animated: true, completion: nil)
}

デリゲートで必要なメソッド
メール送信やキャンセルの操作を受けて実行されます。

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    controller.dismiss(animated: true, completion: nil)

    switch result {
    case .sent: //送信
            break
    case .saved: //保存
            break
    case .failed: //失敗
            break
    case .cancelled: //キャンセル
            break
    default:
        break
    }
}

Xcode: 8.3.2
Swift: 3.1
OS: Sierra 10.12

689 views

GoogleMapの操作 for iOS

GoogleMapの位置や、ズームレベルを変更します。

指定した座標に位置を設定
座標はCLLocationCoordinate2Dで渡します。

let update = GMSCameraUpdate.setTarget(coordinate)

GoogleMapを更新する

mapView.moveCamera(update)

アニメーションで更新する

mapView.animate(with: update)
その他の操作
ZoomIn ズームレベルを1.0拡大
ZoomOut ズームレベルを1.0縮小
ZoomTo ズームレベルを指定します。

それ以外の操作は公式リファレンスを参照ください。
https://developers.google.com/maps/documentation/ios-sdk/views?hl=ja

Xcode: 8.3.2
Swift: 3.1
OS: Sierra 10.12

628 views

座標から住所に変換する 逆ジオコーディング

緯度経度の座標から逆ジオコーディング(リバースジオコーディング)で住所を取得することができます。
これにはGoogleのAPIを利用しますので、GoogleMapsをインポートしている前提でのお話です。

座標をGoogleMapから取得します。
例えばタップであればcoordinate: CLLocationCoordinate2Dが取得できますので
これを元にCLLocationオブジェクトを作成します。

let location: CLLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)

逆ジオコーディングを行うメソッド
結果をアラートで表示しています。

func ReverseGeocoder(location: CLLocation) {

    var address: String = ""

    CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in

        if error != nil {
            print("error")
            return
        }

        if placemarks!.count > 0 {
            let pms = placemarks![0]
            address = self.makeAddressString(placemark: pms)

            let aTitle = "住所表示"
            let aMessage = address
            let alert = UIAlertController(title: aTitle, message: aMessage, preferredStyle: .alert)

            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))

            self.present(alert, animated: false, completion: nil)

        } else {

            print("error")

        }

    })

}

取得できた住所を一連の文字列に変換するメソッド

func makeAddressString(placemark: CLPlacemark) -> String {

    var address: String = ""

    //address += placemark.postalCode != nil ? placemark.postalCode! : ""
    address += placemark.administrativeArea != nil ? placemark.administrativeArea! : ""
    address += placemark.subAdministrativeArea != nil ? placemark.subAdministrativeArea! : ""
    address += placemark.locality != nil ? placemark.locality! : ""
    address += placemark.subLocality != nil ? placemark.subLocality! : ""
    address += placemark.thoroughfare != nil ? placemark.thoroughfare! : ""
    address += placemark.subThoroughfare != nil ? placemark.subThoroughfare! : ""

    return address

}

Xcode: 8.3.2
Swift: 3.1
OS: Sierra 10.12

1,967 views

アラートを表示する UIAlertController

アラートを表示するにはUIAlertControllerを利用します。

アラート(ダイアログ)を表示する

タイトルとメッセージを設定し、アラートのオブジェクトを作成します。

let aTitle = "タイトル"
let aMessage = "メッセージ表示"

let alert = UIAlertController(title: aTitle, message: aMessage, preferredStyle: .alert)

OKボタンを作成します。

alert.addAction(
    UIAlertAction(title: "OK", style: .default, handler: { action in
        print("OKをタップした場合の処理")
    })
)

キャンセルボタンを作成します。
処理は何もしないので、handlerはnilで大丈夫です。

alert.addAction(UIAlertAction(title: "キャンセル", style: .cancel, handler: nil))

アラートを表示する

self.present(alert, animated: false, completion: nil)

続きを読む…»

1,652 views

複数のStoryboardを使った画面遷移

アプリ開発をしていく中で様々な画面を作成していくと、Storyboardが複雑化してしまいます。
そこで、シーンをグループ分けしStoryboardを分割することで開発が楽になります。

今回は別のStoryboardのシーンへ遷移させる方法をご紹介します。

新規ファイルでStoryboardを追加します。

通常はMain.storyboardがありますので、Sub.storyboardを作成します。

ViewControllerを追加し、Storyboard IDを設定します。

仮に「sub_exam」としておきます。

あとは遷移したいところに以下のコードを追加するだけです。

let SubStoryboard: UIStoryboard = UIStoryboard(name: "Sub", bundle: nil)
let subExam: UIViewController = SubStoryboard.instantiateViewController(withIdentifier: "sub_exam")
show(subExam, sender: nil)

Sub.storyboardのViewControllerをイニシャルビューとしている場合は以下のようになります。

let subExam: UIViewController = SubStoryboard.instantiateInitialViewController() as! UIViewController

続きを読む…»

2,707 views