【Swift】UIViewで左右からスライドを出現させる
解説
・3つのStoryBoardを用いる
・色付けしたUILabelをスライドにした
・ContainerViewでViewの描画領域を確保する
・"Left"または"Right"のボタンを押すと、それぞれに対応するStoryBoardのUIViewControllerがアニメーション付きで描画される
・その時、Leftなら左から、Rightなら右側から、出てくるように見える
・LeftViewController,RightViewControllerには一切の記述なし
・UIScreen.main.bounds.width:スクリーンの幅
・UIScreen.main.bounds.height:スクリーンの高さ
・Left (Right) InitFrame:初期のframe(座標位置)
・containerViewDispFrame:Main.StoryBoard(全てのUI部品を司るUIViewController)のframe(つまり原点)
ストーリーボード
ソースコード
import UIKit class ViewController: UIViewController { //MainのViewControllerの右側へViewController移動した座標 let RightViewInitFrame = CGRect(x: UIScreen.main.bounds.width, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) //MainのViewControllerの左側へViewController移動した座標 let LeftViewInitFrame = CGRect(x: -UIScreen.main.bounds.width, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) ////MainのUIViewControllerと同じ座標 let containerViewDispFrame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) @IBOutlet weak var RightView: UIView! { didSet { //StoryBoardのインスタンス let vc = UIStoryboard(name: "Right", bundle: nil).instantiateInitialViewController() RightView.frame = RightViewInitFrame RightView.addSubview(vc!.view) } } @IBOutlet weak var LeftView: UIView! { didSet { let vc = UIStoryboard(name: "Left", bundle: nil).instantiateInitialViewController() LeftView.frame = LeftViewInitFrame LeftView.addSubview(vc!.view) } } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } //画面をタップした時 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesEnded(touches, with: event) //画面を押した時に表示されているviewがRightかLeftだった場合 for touch in touches { if let view = touch.view { //スライドを引っ込める traditionalVC(tag: view.tag) } } } //スライドを引っ込める(元に戻す) func traditionalVC(tag: Int) { //もしRightボタンを押したら if tag == 1 { RightAnimateInitFrame() } //もしLeftボタンを押したら else if tag == 2{ LeftAnimateInitFrame() } } @IBAction func RightButton(_ sender: Any) { //既に左スライドが出てるなら //引っ込める if LeftView.frame == containerViewDispFrame { LeftAnimateInitFrame() } //もしまだ出てないなら右スライドが出てないなら //スライドを出す if RightView.frame != containerViewDispFrame { UIView.animate(withDuration: 0.3, animations: { self.RightView.frame = self.containerViewDispFrame }) //既に右スライドが出てるなら //スライドを引っ込める } else { RightAnimateInitFrame() } } @IBAction func LeftButton(_ sender: Any) { if RightView.frame == containerViewDispFrame { RightAnimateInitFrame() } if LeftView.frame != containerViewDispFrame { UIView.animate(withDuration: 0.3, animations: { self.LeftView.frame = self.containerViewDispFrame }) } else { LeftAnimateInitFrame() } } //右スライドを引っ込める func RightAnimateInitFrame() { UIView.animate(withDuration: 0.3, animations: { self.RightView.frame = self.RightViewInitFrame }) } //左スライドを引っ込める func LeftAnimateInitFrame() { UIView.animate(withDuration: 0.3, animations: { self.LeftView.frame = self.LeftViewInitFrame }) } }
【Swift】TableViewを使ったパララックスアニメーション
解説
※注意
・ソースコードが複雑で、僕もよくわかってない
・”パララックス”という視覚効果
↓参考動画
・セルをスクロールすると、セル内のImageViewがパララックスの視覚効果をもたらす
ストーリーボード
ソースコード
import UIKit class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell") tableView.reloadData() paralex() } //画像の視覚効果を実装する func paralex() { guard let tableViewRows = tableView.indexPathsForVisibleRows else { return } for indexPath in tableViewRows { //セルを生成 guard let cell = tableView.cellForRow(at: indexPath) as? CustomCell else { continue } //indexPathに該当するセルのdraw(描く)area(領域)をCGRectで返す let rect = tableView.rectForRow(at:indexPath) //rectでtableViewに表示するための座標を読み込む let rectInTable = tableView.convert(rect, to: tableView.superview) //?? let offset = rectInTable.origin.y + rectInTable.height / 2 //tableViewの数だけoffsetを割る? let offsetRatio = offset / tableView.bounds.height //セルのimageViewのframe(描画後の座標)を取得 var imageViewRect = cell.paralexImageView.frame //?? imageViewRect.origin.y = offsetRatio * 100 * -1 //?? cell.paralexImageView.frame = imageViewRect } } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 8 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 165 } //スクロールした時に視覚を変化させる func scrollViewDidScroll(_ scrollView: UIScrollView) { paralex() } }
ソースコード2
import UIKit class CustomCell: UITableViewCell { //ImageViewで紐付けすると、エラーがでる //既にカスタムクラスにはimageViewがあるらしいから //同じ名前ではなくimageView以外の名前に推奨 @IBOutlet weak var paralexImageView: UIImageView! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } }
【Swift】MPMusicPlayerで音楽プレイヤーを作る
完成図
解説
・プロセス
- 起動直後にライブラリから曲を選択させられる
- 選択して、左上の完了を押すと、プレイヤー画面へと移行
- 再生/停止ボタンを押せば、再生/停止ができる
- 中央のバー(ScrubBar)で好きな再生位置に移動できる
- もし他の曲を再生したいなら、下の”選曲画面へ”を押せばいい
・MPMusicPlayerで音楽プレイヤーを実装
・他にもAVFoundationを使う方法もある
・曲の再生位置は、player.currentPlaybackTime、の数値
・再生/停止をするたびに、再生位置をTimeInterval型の変数に保存し、currentPlaybackTimeに入れる作業を繰り返す
・timer関数でScrubBarを0.5秒間隔で移動させている
・めっちゃ参考になった記事
↓
[iOS][Swift]ミュージックライブラリにアクセスして音楽を再生する(MPMusicPlayerController使用) – nackpan Blog
・もっとおしゃれな音楽プレイヤーを作るなら、こちらもおすすめ
↓
ストーリーボード
ソースコード
import UIKit import MediaPlayer class ViewController: UIViewController,MPMediaPickerControllerDelegate { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var songname: UILabel! @IBOutlet weak var artistname: UILabel! @IBOutlet weak var playButton: UIButton! @IBOutlet weak var scrubBar: UISlider! //MediaPlayerのインスタンスを作成 var player:MPMusicPlayerController! //タイマー変数を定義 var timer = Timer() //次に再生するか一時停止するかを判断 var playorpause = 0 //曲が再生される前かされた後かを判定 var flag = 0 //曲の現在位置を一次的に保持 var currenttime = 0.0 //曲の長さを保持する変数 var timeinterval = TimeInterval() override func viewDidLoad() { super.viewDidLoad() //プレイヤーの準備 player = MPMusicPlayerController.applicationMusicPlayer //?? let notificationcenter = NotificationCenter.default notificationcenter.addObserver(self, selector: #selector(type(of: self).nowPlayingItemChanged(notification:)), name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange, object: player) //初期化 scrubBar.value = 0.0 //再生されてないのにタップしてエラーが出るのを防ぐため scrubBar.isHidden = true //初期画面をピッカー画面にする //誤って、再生ボタンを押してエラーが出るのを防ぐため //MPMediaPickerのインスタンス let picker = MPMediaPickerController() //ピッカーのデリゲートを設定 picker.delegate = self //複数選択を不可にする picker.allowsPickingMultipleItems = true //ピッカー画面を表示 present(picker, animated: true, completion: nil) // Do any additional setup after loading the view, typically from a nib. } //再生中の曲が変更された時に実行 @objc func nowPlayingItemChanged(notification:NSNotification) { //もし再生できる状態なら if let playingitem = player.nowPlayingItem { updatesong(mediaItem: playingitem) } } //使用した〇〇を破棄する deinit { let notificationcenter = NotificationCenter.default notificationcenter.removeObserver(self, name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange, object: player) // player.endGeneratingPlaybackNotifications() } //曲の情報を表示する func updatesong(mediaItem: MPMediaItem) { //曲情報を表示 songname.text = mediaItem.albumTitle ?? "不明なタイトル" artistname.text = mediaItem.albumArtist ?? "不明なアーティスト" timeinterval = mediaItem.playbackDuration //アートワークを表示 if let artwork = mediaItem.artwork { //アートワークの枠サイズを設定 let image = artwork.image(at: imageView.bounds.size) //imageviewにがアートワークを設定する imageView.image = image } else { //もしアートワークがなければ、何も表示しない imageView.image = nil } } //ピッカー画面で曲が選択された時 func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) { //プレイヤーを止める player.stop() //選択した曲をplayerにセット player.setQueue(with: mediaItemCollection) //選択した曲の情報をラベルやイメージビューにセット if let mediaitem = mediaItemCollection.items.first { updatesong(mediaItem: mediaitem) } //ピッカーを閉じて、破棄する dismiss(animated: true, completion: nil) } //スライダーの位置を曲の再生位置と同期する @objc func updateslider(){ self.scrubBar.setValue(Float(self.player.currentPlaybackTime), animated: true) } //曲が選択されなかった時 func mediaPickerDidCancel(_ mediaPicker: MPMediaPickerController) { dismiss(animated: true, completion: nil) } //選択画面へを押した場合 @IBAction func pick(_ sender: Any) { //flag変数を初期化 flag = 0 //timerを破棄する timer.invalidate() //プレイヤーを一旦停止する player.pause() //曲が停止されたことを示す playButton.setImage(UIImage(named: "play.png"), for: UIControl.State()) //MPMediaPickerのインスタンス let picker = MPMediaPickerController() //ピッカーのデリゲートを設定 picker.delegate = self //複数選択を不可にする picker.allowsPickingMultipleItems = true //ピッカー画面を表示 present(picker, animated: true, completion: nil) } @IBAction func play(_ sender: Any) { //もし停止中なら if playorpause == 0{ //保持した位置を代入 player.currentPlaybackTime = currenttime //再生 player.play() //再生中であることを示す playorpause = 1 //画像を再生のマークに playButton.setImage(UIImage(named: "pause.png"), for: UIControl.State()) //もしまだ1度も再生されてなければ if flag == 0 { scrubBar.isHidden = false scrubBar.maximumValue = Float(timeinterval) flag = 1 } //スライダーと曲を同期 timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(updateslider), userInfo: nil, repeats: true) } //もし曲が再生中なら else { //停止した位置を保持 currenttime = player.currentPlaybackTime //タイマーを停止し、曲を一時停止 timer.invalidate() player.pause() playorpause = 0 playButton.setImage(UIImage(named: "play.png"), for: UIControl.State()) } } //次の曲へ @IBAction func next(_ sender: Any) { player.skipToNextItem() playButton.setImage(UIImage(named: "play.png"), for: UIControl.State()) } //前の曲へ @IBAction func back(_ sender: Any) { player.skipToPreviousItem() playButton.setImage(UIImage(named: "play.png"), for: UIControl.State()) } //スライダーを移動した位置を曲の再生位置に設定 @IBAction func scrubAction(_ sender: Any) { player.currentPlaybackTime = TimeInterval(scrubBar.value) currenttime = player.currentPlaybackTime } }
【Swift】ImageViewの使い方
完成図
解説
・プロセス
- 1つ目の画像が表示される
- 画面をタップ
- (4つ目まで繰り返し)
- 4つ目の画像をタップ
- (最初に戻る)
・viewDidLoad()する前にimage_arrayに画像を入れたかったが、エラーが出たので断念。
・タップすると画像が切り替わる動作は、touchesBeganで実装
ストーリーボード
ソースコード
import UIKit class ViewController: UIViewController { @IBOutlet weak var ImageView: UIImageView! //画像を用意する let image0 = UIImage(named: "壁紙1.jpg") let image1 = UIImage(named: "壁紙2.jpg") let image2 = UIImage(named: "壁紙3.jpg") let image3 = UIImage(named: "壁紙4.jpg") //複数の画像を入れる配列 var image_array = [UIImage]() //カウンタ変数 var count = 0 override func viewDidLoad() { super.viewDidLoad() //画像を格納した配列を用意 image_array = [image0!,image1!,image2!,image3!] } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } //タップ時に呼ばれる override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { ImageView.image = image_array[count] //もし4つ目の画像になったら if count == 3 { count = -1 } //カウンタ変数を更新 count += 1 } }