ios11 自分のアプリをApp Storeのおすすめに取り上げてもらう方法。
良い記事を見つけた!
自分のアプリをAppStoreのおすすめに取り上げてもらえるようにお願いできるようになったとか。
ぜひやってみたい!!
medium.com
swift3.0: Arrayの中身をソートする。
Arrayの中身が独自クラスの場合のソート方法
class Item: NSObject { var id: String = "" var itemName: String = "" } class data: NSObject { func prepareItem() { ///ソートするためのデータを用意する var list: [Item] = [] let item1: Item = Item() item1.id = "id_a" item1.itemName = "aaa" list.append(item1) let item2: Item = Item() item2.id = "id_b" item2.itemName = "bbb" list.append(item2) let item3: Item = Item() item3.id = "id_c" item3.itemName = "ccc" list.append(item3) ///ソート用のデータlistをソートする(昇順) let ascending : [Item] = list.sorted(by: {$0.itemName < $1.itemName}) ///ソート用のデータlistをソートする(降順) let descending: [Item] = list.sorted(by: {$0.itemName > $1.itemName}) } }
UIViewを曲線上にアニメーションさせる方法
今回は半径分だけアニメーションさせて見ます。
まずは全コードを。。
開発環境:Xcode8 + swift3
スタートボタンのイベントはIBかストーリーボードで設定して繋げてください。
import UIKit class CurveAnimationViewController: UIViewController { let animateView: UIView = UIView() let viewSize: CGFloat = 100.0 let curcleRadius: CGFloat = 150.0 let duration: TimeInterval = 0.5 var isDownView: Bool = false override func viewDidLoad() { super.viewDidLoad() animateView.frame = CGRect(x: (UIScreen.main.bounds.width / 2) - (viewSize / 2), y: UIScreen.main.bounds.height / 2 - viewSize / 2, width: viewSize, height: viewSize) animateView.layer.cornerRadius = viewSize / 2.0 animateView.backgroundColor = UIColor.orange self.view.addSubview(animateView) } @IBAction func tappedStartButton(_ sender: UIButton) { isDownView = !isDownView if isDownView { self.downAnimation() }else{ self.upAnimation() } } } //MARK: - animation extension CurveAnimationViewController { func downAnimation() { animateView.layer.removeAnimation(forKey: "end") let animation: CAKeyframeAnimation = self.animation() let path: CGMutablePath = CGMutablePath() let startPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: animateView.frame.minY + (animateView.frame.height / 2.0)) let midPoint: CGPoint = CGPoint(x: startPoint.x + curcleRadius, y: startPoint.y + curcleRadius / 2.0) let endPoint: CGPoint = CGPoint(x: startPoint.x, y: startPoint.y + curcleRadius) path.move(to: startPoint) path.addQuadCurve(to: endPoint, control: midPoint) animation.path = path animateView.layer.add(animation, forKey: "start") } func upAnimation() { animateView.layer.removeAnimation(forKey: "start") let animation: CAKeyframeAnimation = self.animation() let path: CGMutablePath = CGMutablePath() let startPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: animateView.frame.minY + (animateView.frame.height / 2.0) + curcleRadius) let midPoint: CGPoint = CGPoint(x: startPoint.x + curcleRadius, y: startPoint.y - curcleRadius / 2.0) let endPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: startPoint.y - curcleRadius) path.move(to: startPoint) path.addQuadCurve(to: endPoint, control: midPoint) animation.path = path animateView.layer.add(animation, forKey: "end") } func animation() -> CAKeyframeAnimation { let animation: CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position") animation.fillMode = kCAFillModeForwards animation.isRemovedOnCompletion = false animation.duration = duration return animation } }
詳しく説明をしていきます。
今回はUIViewをアニメーションさせるためにCAKeyframeAnimation
を使用しています。
func animation() -> CAKeyframeAnimation
内で設定している内容は下記の通りです。
CAKeyframeAnimation | 説明 |
---|---|
fillMode | アニメーションの再生中もしくは再生後のスタイル。 プロパティについてはこちらのサイトがわかりやすくまとめていました。【iOS Swift アニメーション入門 #4】Core AnimationのfillModeプロパティ | Swift,Objective-Cプログラミング ~ iOS ~ |
isRemovedOnCompletion | アニメーション完了時に、ターゲットのレイヤーからアニメーションを削除するかどうかを設定。デフォルトはYes |
duration | アニメーションの長さ。 |
このCAKeyframeAnimationに作成したパスを入れて、動かしたいUIViewのレイヤーに加えてあげればアニメーションが開始されます。
では、パスをどのように設定しているか見ていきしょう。
let path: CGMutablePath = CGMutablePath() //出発地点 > 動かしたいViewのセンターを計算しています。 let startPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: animateView.frame.minY + (animateView.frame.height / 2.0) + curcleRadius) //中間地点 > 出発地点と最終地点の真ん中の位置を計算します。 let midPoint: CGPoint = CGPoint(x: startPoint.x + curcleRadius, y: startPoint.y - curcleRadius / 2.0) //最終地点 > 最終地点のポジション。 let endPoint: CGPoint = CGPoint(x: animateView.frame.minX + (animateView.frame.width / 2.0), y: startPoint.y - curcleRadius) //出発地点のポイントを設定します。 path.move(to: startPoint) //最終地点と中間地点を設定します。 path.addQuadCurve(to: endPoint, control: midPoint) //先ほどのCAKeyframeAnimationにパスを設定。 animation.path = path //UIViewにCAKeyframeAnimationを追加。 animateView.layer.add(animation, forKey: "start")
pathの数値を変えるなどして試して見てください。
特に難しい計算を必要とせずに、どこに向かってアニメーションさせたいかのポイントを入れるだけなので、とても簡単に実装できます。
CocoaPods:ライブラリを追加する
すでにあるPodfileに、他のライブラリをさらに追加してインストールしたい。
そんな時も、初めてPodfileに書いたライブラリをインストールする時も、インストールする時はどんな時も $ pod install
を使おう!
間違っても $ pod update
もしくは $ pod update [PODNAME]
は使わない。
なぜか?それは、update と install の違いを見ると明らかです。
※わりと $ pod update
を使えと書いてある記事が多いので注意してください。
$ pod install
Podfileに書かれたライブラリをプロジェクトにインストールします。
Podfileに新しく追記されたライブラリだけをインストールするので、すでにインストール済みのライブラリは何も変化しません。
ただしPodfileから削除したライブラリはアンインストールされます。
$ pod update
すでにインストールされているライブラリのバージョンをアップデートします。
インストール済みのライブラリとPodfileに新しく記述したバージョン(バージョン指定していない時は、最新のバージョン)が異なっている場合、アップデートを開始します。
pod nameを指定していないと全てのライブラリが更新されてしまいますので注意が必要です。
ちなみに・・・
Podfileが置かれているディレクトリにPodfile.lockというファイルがあります。
このPodfile.lockというファイルにはインストールしたライブラリのバージョン情報が書かれおり、$ pod update
した時にはこのファイルを見てアップデートをする必要があるかどうかを判別しています。
詳しくは本家サイトにも書かれていますので、参考にしてください。
guides.cocoapods.org
初めてCocoaPodsを導入する方は、下記の記事がとても分かりやすかったのでオススメです。
qiita.com
UINavigationControllerを使わない時のナビゲーションバーがステータスバーに被らない件。
タイトルがわかりにくくてごめんなさい。
つまり、こういうことデス。
はい、とてもかっこ悪いので修正していきます。
いつも通り完コピ用ソースです。
開発環境:Xcode8 + swift3
import UIKit class ViewController: UIViewController,UINavigationBarDelegate { @IBOutlet weak var navigationBar: UINavigationBar! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. navigationBar.delegate = self } func position(for bar: UIBarPositioning) -> UIBarPosition { return .topAttached } }
やっていることは簡単で、UINavigationBarDelegateのfunc position(for bar: UIBarPositioning) -> UIBarPosition
を実装するだけ。
戻り値は.topAttached
。
navigationBar.delegate = self
を忘れずに。。
swift: テキストの高さを取得する簡単な方法(UITextView,UILabel)
なんだかんだでよく使う、表示されるテキストの高さを取得する方法。
開発環境:Xcode8 + swift3
UILabel
func labelHeight(label: UILabel) -> CGFloat{ label.sizeToFit() return label.frame.height }
UITextView
func textViewHeight(textView: UITextView) -> CGFloat { return textView.contentSize.height }
ただ、上記の方法だとUIから直接取得しているのでAutoLayoutのタイミングとか、Viewを読み込む処理スピードの低下とか色々都合が悪い時がある。 その場合は、NSStringクラスを使用して高さを取得しよう!
func labelHeight(label: UILabel, s: String) -> CGFloat { let str: NSString = NSString(string: s) let size : CGSize = CGSize(width: label.frame.width, height: CGFloat.greatestFiniteMagnitude) let att: [String: Any] = [NSFontAttributeName: label.font] let rect: CGRect = str.boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: att, context: nil) return rect.height }
高さを取得しているのはNSStringクラスのstr.boundingRect(with: CGSize, options: NSStringDrawingOptions, attributes: [String : Any]?, context: NSStringDrawingContext?)
メソッド。
設定する引数は下記の通り。
引数 | 説明 |
---|---|
CGSize | 表示するUIのサイズ。高さを取得したい場合は幅を表示サイズに、高さをCGFloat.greatestFiniteMagnitude に設定。 幅を取得したい場合はその逆。 |
NSStringDrawingOptions | テキストの表示方法。 2007-06-19 - at_yasuの日記もといメモ書きにわかりやすく記載してある。 |
[String : Any]? | Attributesを設定。特にAttributedStringとかを使用していない場合は、[NSFontAttributeName: label.font] で良いです。 |
UITextViewの場合はUILabelをUITextViewに書き換えて使用してください。
UITableViewを実装してみよう!
iOSエンジニアとして最初の登竜門的なUIがUITableViewだと思う。
これが理解できたらある程度どんなアプリも開発できる気がする。
まずは基本的な実装方法を。。。
Xcodeでプロジェクトを作成しておいてください。
開発環境:Xcode8 + swift3
1.UITableViewCellを準備しよう
UITalbeViewCellとはテーブルビュー内で表示されるリストの内容です。
基本的に同じデザインを繰り返し表示させる仕組みのため、スクリーンから消えたセルは次に表示されるセルに使い回されます。
エコですね!
UITalbeViewCellのファイルを追加します。
Xcode上で⌘+n
>Cocoa Touch Class
を選択してNextボタンをタップすると下記の様な感じになります。
- Class: 任意のクラス名を入力(今回は
TableViewCell
とします) - Subclass of:
UITableViewCell
と入力 - Also create XIB file のチェックボックスをONにする
上記の様に入力したらNextボタンをタップしてCellのクラスを作成してください。
ファイルが2つ追加されているはずです。
- TableViewCell.swift
- TableViewCell.xib
cellのUIを完成させよう!
今回はUILabelを二つ用意しました。
右上で四角に囲ってあるidentifierへの入力をお忘れなく。後ほどUITableViewを実装するときに使用します。
任意のidを入力しますが、今回はTableViewCell
にしました。xibのファイル名と同名にすると分かりやすくて良いと思います。
TableViewCell.swiftにコードを書いて行こう!
いきなり完成コード全文。
全コピペ対応してますww
import UIKit class TableViewCell: UITableViewCell { //TableViewCell.xibで追加したUILabelを繋げる。 @IBOutlet weak var label: UILabel! @IBOutlet weak var nameLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() // Initialization code //このメソッドは初回1回だけ呼ばれますので、1回だけで良い処理(初期化処理)はここに書きます。 } //UITableViewで呼び出す用のメソッド。 //ここでUILabelのテキストを変更しています。 func setupCell(words: String?, name: String?) { label.text = words ?? "no text" nameLabel.text = name ?? "no name" } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } }
これでUITableViewCellの処理は完成です✨
2.UITableViewを実装しよう!
いよいよメインテーマのテーブルビューです!
基本的な実装はとても簡単です。肩の力を抜いていきましょー。
StoryboardにUITableViewを追加する
こんな感じでUITableViewをUIViewController全体にベタッと貼り付けます。
今回はUINavigationControllerもつけていますが、つけなくても大丈夫です。
ちなみにUINavigationControllerと合わせて使うケース、非常に多いと思います。
今回のようにUITableViewをUIViewController全体に貼り付ける場合、Adjust Scroll View Insetsにチェックを入れてください。でなければ、NavigationBarとTableViewが被ってしまいます。
右の画像はUIViewControllerの設定です。参考にしてください。
ViewController.swiftにUITableViewを実装する
先ほどのStoryboardでテーブルビューを貼り付けたViewControllerのファイルにコードを追加していきます。
完成コードはこちら。
import UIKit class ViewController: UIViewController { //StoryboardからTableViewを繋げておきます。 @IBOutlet weak var tableView: UITableView! //テーブルビューで表示させるデータ。表示内容が多い場合などはstractとかクラスを使うケースが多いかもしれませんが //今回はArrayの中にDictionaryを入れ子にした設計で簡単に済ませています。 var data: [[String:String]] { get { //それぞれ"words"と"name"をkeyにしたdictionaryを生成 let w1: [String: String] = ["words" : "歳をとればとるほど、動機こそが大切だという核心が深まる。", "name" : "スティーブ・ジョブズ"] let w2: [String: String] = ["words" : "キャリアではない。私の人生なんだ。", "name" : "スティーブ・ジョブズ"] let w3: [String: String] = ["words" : "何を捨てるかで誇りが問われ、何を守るかで愛情が問われる。", "name" : "スティーブ・ジョブズ"] let w4: [String: String] = ["words" : "昔を振り返るのはここでやめにしよう。大切なのは明日何が起きるかだ。", "name" : "スティーブ・ジョブズ"] let w5: [String: String] = ["words" : "大事なのは自分の心に素直になることだ。", "name" : "スティーブ・ジョブズ"] //arrayを生成して上記のdictionaryを追加していきます。 var d: [[String:String]] = [] d.append(w1) d.append(w2) d.append(w3) d.append(w4) d.append(w5) return d } } override func viewDidLoad() { super.viewDidLoad() //dataSourceにselfを設定(これを忘れると、まっさらのTableViewが表示されることとなります) self.tableView.dataSource = self self.tableView.delegate = self //このtableviewで使用するcellを登録します。幾つでも登録できます! let nib : UINib = UINib(nibName: "TableViewCell", bundle: nil) //forCellReuseIdentifierにはxibファイル内で登録したidentifierと同じ文字列を入れましょう! self.tableView.register(nib, forCellReuseIdentifier: "TableViewCell") //テーブルビューの余分なセパレーターが気になったから消しちゃいます。 self.tableView.tableFooterView = UIView() } } extension ViewController: UITableViewDataSource { //UITableViewをコントロールするDataSourceを実装します。(最低限必要なメソッドは下記2つのみ!) //テーブルビューはまずこのメソッドが呼ばれます。セクションの中でデータがいくつ必要かの数を返します。 //今回はセクションが1つしかないので、dataの数をそのまま返します。 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return data.count } //セルに値をセットするにはこのメソッドを使います。 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { //indexPathを元にデータを抽出。 let d : [String : String] = data[indexPath.row] //cellを呼び出して値をセットしていきます。(identifierはxibファイルで登録したものと同じ文字列を!) let cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell cell.setup(words: d["words"], name: d["name"]) return cell } } extension ViewController: UITableViewDelegate { //テーブルビューのセルが選択されたときに呼ばれます。 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { //選択されたセルの色を解除します。 tableView.deselectRow(at: indexPath, animated: true) let d : [String : String] = data[indexPath.row] print("「\(d["words"] ?? "no data")」が選択されました!") } }
こちらも全文コピペ対応済みww
貼り付けて実行して色々と触ってみてください。思ったより簡単に実装できるはずです。
不明点だったり、うまくできなかった方はコメントください。
わかる範囲でお答えいたします。