環境
Xcode 11.3
swift 5.1.3
CocoaPods 1.8.4
要件
機能要件
アプリのバックグラウンドに、ユーザーの選んだ画像を設定する機能
仕様
- 「背景に画像を設定するボタン」をタップ
- 背景画像設定画面の表示
- カメラロール内の画像一覧を表示
- 画像をタップすることで、拡大表示
- オッケーボタンを押すことで、画像がアプリ内部に保存される
- その段階で、アプリの背景に選択した画像が表示される
- 設定完了後、「背景に画像を設定するボタン」が表示されているもとのページに戻る
設計
写真選択
背景に画像を設定するボタンタップ後、背景画像設定用の画面を表示。
カメラロール内の画像一覧を表示し、画像を選択させる。
選択後、選択した画像が背景に拡大表示されるようにする。
storyboard上の設定
TopViewControllerに対して
- UIButtonを追加
- storyboardIDを、
topView
に設定
SetBackgroundImageViewControllerに対して
- 背景画像設定用の新規コントローラーの作成(SetBackgroundImageViewController)
- UIButton,imageViewを設置
- storyboardIDを
backgroundImageView
に設定
コードの記述
TopViewController.swift
import UIKit
class TopViewController: UIViewController {
// 背景image設定ページへ
// Btnが押されたときのaction
@IBAction func showImageSelection(_ sender: Any) {
// コントローラーの指定
let backgroundImageController = self.storyboard?.instantiateViewController(withIdentifier: "backgroundImageView") as! SetBackgroundImageViewController
// 全画面表示で画面遷移
backgroundImageController.modalPresentationStyle = UIModalPresentationStyle(rawValue: 0)!
self.present(backgroundImageController, animated: false, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
print("user view did load")
}
}
SetBackgroundImageViewController
import UIKit
class SetBackgroundImageViewController: UIViewController {
// 背景設定
@IBOutlet weak var backgroundImageView: UIImageView!
var backgroundImage:UIImage!
var themaColor:UIColor!
// ボタンのoutlet接続およびaction接続
// 戻るボタン
@IBOutlet weak var rerturnBtn: boundButton!
@IBAction func returnBtnPushed(_ sender: Any) {
}
// 画像選択ボタン
@IBOutlet weak var selectBtn: UIButton!
@IBAction func selectBtnPushed(_ sender: Any) {
}
// 決定ボタン
@IBOutlet weak var setBtn: UIButton!
@IBAction func setBtnPushed(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
// imagePickerを表示
addImagePickerView()
}
}
// imagePickerViewの設定用
extension SetBackgroundImageViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
func addImagePickerView() {
print("pushed image!")
//imagePickerViewを表示する
let pickerController = UIImagePickerController()
pickerController.sourceType = .photoLibrary
pickerController.delegate = self
self.present(pickerController, animated: true, completion: nil)
}
// pickerの選択がキャンセルされた時の処理
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
選択画像表示
画像が選択されたら、コントローラーのimageViewに表示されるようにする。
SetBackgroundImageViewController.swift
// imagePickerViewの設定用
extension SetBackgroundImageViewController {
// 以下の関数を追加
// 写真が選択された時の処理
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// 選択されたimageを取得
guard let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage? else {return}
// imageをimageViewに設定
backgroundImage = selectedImage
backgroundImageView.image = backgroundImage
// imagePickerの削除
self.dismiss(animated: true, completion: nil)
}
}
選択画像保存
決定ボタン押下時、選択されている画像をアプリ内に保存。
処理終了後に、topページに戻る。
SetBackgroundViewController.swift
import UIKit
class SetBackgroundImageViewController: UIViewController {
// 背景設定
@IBOutlet weak var backgroundImageView: UIImageView!
var backgroundImage:UIImage!
var themaColor:UIColor!
// ボタン接続
// 戻るボタン
@IBOutlet weak var rerturnBtn: boundButton!
@IBAction func returnBtnPushed(_ sender: Any) {
}
// もう一度選ぶボタン
@IBOutlet weak var selectBtn: UIButton!
@IBAction func selectBtnPushed(_ sender: Any) {
}
// 確定ボタン
@IBOutlet weak var setBtn: UIButton!
@IBAction func setBtnPushed(_ sender: Any) {
// ここから追記
// backgroundImage.pngという名前で保存
let imagePath = self.fileInDocumentsDirectory(filename: "backgroundImage.png")
if saveImage(image: backgroundImage, path: imagePath) {
// 画像を設定
let topVC = self.presentingViewController as! TopViewController
topVC.backgroundImage.image = backgroundImage
// もとの画面(TopViewController)に戻る
self.dismiss(animated: false, completion: nil)
} else {
backgroundImage = nil
}
// ここまで追記
}
override func viewDidLoad() {
super.viewDidLoad()
// imagePickerを表示
addImagePickerView()
}
}
// ここから追記
// imageの保存関数
extension BackgroundImageViewController {
// DocumentディレクトリのfileURLを取得
func getDocumentsURL() -> NSURL {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as NSURL
return documentsURL
}
// ディレクトリのパスにファイル名をつなげてファイルのフルパスを作る
func fileInDocumentsDirectory(filename: String) -> String {
let fileURL = getDocumentsURL().appendingPathComponent(filename)
return fileURL!.path
}
// ファイルに書き込み
func saveImage (image: UIImage, path: String ) -> Bool {
let pngImageData = image.pngData()
do {
try pngImageData!.write(to: URL(fileURLWithPath: path), options: .atomic)
} catch {
print(error)
return false
}
return true
}
}
// ここまで追記
// imagePickerViewの設定用
extension SetBackgroundImageViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
func addImagePickerView() {
print("pushed image!")
//imagePickerViewを表示する
let pickerController = UIImagePickerController()
pickerController.sourceType = .photoLibrary
pickerController.delegate = self
self.present(pickerController, animated: true, completion: nil)
}
// pickerの選択がキャンセルされた時の処理
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
// 写真が選択された時の処理
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
// 選択されたimageを取得
guard let selectedImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage? else {return}
// imageをimageViewに設定
backgroundImage = selectedImage
backgroundImageView.image = backgroundImage
// imagePickerの削除
self.dismiss(animated: true, completion: nil)
}
}
保存画像のロード・表示
以下の関数を用意しておき、背景画像を表示させたいところで呼び出す。
// imageをload
func loadBackgroundImage() -> UIImage? {
let image = UIImage(contentsOfFile: fileInDocumentsDirectory(filename: "backgroundImage.png"))
if image == nil {
print("backgroundImage is missing")
}
return image
}
参考ページ
teratail : エラー:which is already presenting (null)の対処法
qiita : 【Swift4】URL先の画像をアプリ内に保存&ロードする
HatenaBlog : iOSでアプリ内部(Document)に画像(UIImage)を保存する方法【iOSアプリ開発】