Sad Face Makerという写真の編集アプリです。Twitterの投稿機能について学ぶことができました。こちらはQiitaの記事としてまとめています。
アプリを使うとこのようなGIFアニメーションを簡単に作ることができます。
*** Terminating app due to uncaught exception 'GADInvalidInitializationException', reason: 'The Google Mobile Ads SDK was initialized incorrectly. Google AdMob publishers should follow instructions here: https://googlemobileadssdk.page.link/admob-ios-update-plist to include the AppMeasurement framework, set the -ObjC linker flag, and set GADApplicationIdentifier with a valid App ID. Google Ad Manager publishers should follow instructions here: https://googlemobileadssdk.page.link/ad-manager-ios-update-plist'
![]() |
| 日本語版 |
![]() |
| 英語版 |
When the value of this property is false (the default), views analyze touch events in UITouch.Phase.began and UITouch.Phase.moved in parallel with the receiver.
class TwoDimentionsPinchGestureRecognizer : UIPinchGestureRecognizer {
private var initPinchWidth : CGFloat = 0
private var initPinchHeight : CGFloat = 0
private var _scaleX : CGFloat = 0
private var _scaleY : CGFloat = 0
var scaleX : CGFloat {
get { return _scaleX }
}
var scaleY : CGFloat {
get { return _scaleY }
}
override func touchesBegan(_ touches: Set, with event: UIEvent) {
guard touches.count == 2 else { return }
let locations = touches.compactMap { touch in
return touch.location(in: self.view)
}
initPinchWidth = abs(locations[0].x - locations[1].x)
initPinchHeight = abs(locations[0].y - locations[1].y)
super.touchesBegan(touches, with: event)
}
override func touchesMoved(_ touches: Set, with event: UIEvent) {
guard touches.count == 2 else { return }
guard initPinchWidth != 0 else { return }
guard initPinchHeight != 0 else { return }
let locations = touches.compactMap { touch in
return touch.location(in: self.view)
}
let newPinchWidth = abs(locations[0].x - locations[1].x)
let newPinchHeight = abs(locations[0].y - locations[1].y)
_scaleX = newPinchWidth / initPinchWidth
_scaleY = newPinchHeight / initPinchHeight
super.touchesMoved(touches, with: event)
}
override func touchesEnded(_ touches: Set, with event: UIEvent) {
initPinchWidth = 0
initPinchHeight = 0
super.touchesEnded(touches, with: event)
}
}
class TwoDimentionsPinchGestureRecognizer : UIPinchGestureRecognizer {
private var initPinchWidth : Float = 0
private var initPinchHeight : Float = 0
private var _scaleX : Float = 0
private var _scaleY : Float = 0
var scaleX : Float {
get { return _scaleX }
}
var scaleY : Float {
get { return _scaleY }
}
override func touchesBegan(_ touches: Set, with event: UIEvent) {
super.touchesBegan(touches, with: event)
guard touches.count == 2 else { return }
let locations = touches.compactMap { touch in
return touch.location(in: self.view)
}
initPinchWidth = Float(abs(locations[0].x - locations[1].x))
initPinchHeight = Float(abs(locations[0].y - locations[1].y))
}
override func touchesMoved(_ touches: Set, with event: UIEvent) {
super.touchesMoved(touches, with: event)
guard touches.count == 2 else { return }
let locations = touches.compactMap { touch in
return touch.location(in: self.view)
}
let newPinchWidth = Float(abs(locations[0].x - locations[1].x))
let newPinchHeight = Float(abs(locations[0].y - locations[1].y))
_scaleX = newPinchWidth / initPinchWidth
_scaleY = newPinchHeight / initPinchHeight
}
}
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var label: UILabel!
enum ButtonId {
case one
case two
}
var selectedButton = ButtonId.one
var selectedRow = 0
let button1List : [String] = ["apple", "orange", "banana", "grape", "strawberry"]
let button2List : [String] = ["black", "white"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
@IBAction func pushButton1(_ sender: Any) {
selectedButton = .one
showAlert()
}
@IBAction func pushButton2(_ sender: Any) {
selectedButton = .two
showAlert()
}
func update() {
switch selectedButton {
case .one:
label.text = button1List[selectedRow]
case .two:
label.text = button2List[selectedRow]
default:
break
}
}
private func showAlert() {
let vc = UIViewController()
vc.preferredContentSize = CGSize(width: 250,height: 250)
let pickerView = UIPickerView(frame: CGRect(x: 0, y: 0, width: 250, height: 250))
pickerView.delegate = self
pickerView.dataSource = self
vc.view.addSubview(pickerView)
var title = ""
switch selectedButton {
case .one:
title = "fruit"
case .two:
title = "color"
default:
break
}
let editAlert = UIAlertController(title: title, message: "", preferredStyle: UIAlertController.Style.alert)
editAlert.setValue(vc, forKey: "contentViewController")
editAlert.addAction(UIAlertAction(title: "done", style: .default, handler: { (UIAlertAction) in
self.selectedRow = pickerView.selectedRow(inComponent: 0)
self.update()
}))
editAlert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
self.present(editAlert, animated: true)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch selectedButton {
case .one:
return button1List.count
case .two:
return button2List.count
default:
return 0
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch selectedButton {
case .one:
return button1List[row]
case .two:
return button2List[row]
default:
return nil
}
}
}
func update(_ selectedRow : Int) {
switch selectedButton {
case .one:
label.text = button1List[selectedRow]
case .two:
label.text = button2List[selectedRow]
default:
break
}
}
private func showAlert() {
let vc = UIViewController()
vc.preferredContentSize = CGSize(width: 250,height: 250)
let pickerView = UIPickerView(frame: CGRect(x: 0, y: 0, width: 250, height: 250))
pickerView.delegate = self
pickerView.dataSource = self
vc.view.addSubview(pickerView)
var title = ""
switch selectedButton {
case .one:
title = "fruit"
case .two:
title = "color"
default:
break
}
let editAlert = UIAlertController(title: title, message: "", preferredStyle: UIAlertController.Style.alert)
editAlert.setValue(vc, forKey: "contentViewController")
editAlert.addAction(UIAlertAction(title: "done", style: .default, handler: { (UIAlertAction) in
let selectedRow = pickerView.selectedRow(inComponent: 0)
self.update(selectedRow)
}))
editAlert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: nil))
self.present(editAlert, animated: true)
}




override func viewDidLoad() {
super.viewDidLoad()
// NavigationBarの高さ × 0.8にアイコンのサイズを指定する
let barHeight : Int = Int((self.navigationController?.navigationBar.frame.size.height)! * 0.8)
// Ioniconよりメニューアイコン画像をロード
let menuIcon = UIImage.imageWithIonicon(ionicon.AndroidMenu, color: UIColor.black, iconSize: CGFloat(barHeight), imageSize: CGSize(width: barHeight, height: barHeight))
// アイコン画像からUIBarButtonItemを生成
let leftNavEditButtonItem = UIBarButtonItem(image: menuIcon, style: .plain, target: self, action: #selector(MyViewController.doSomething))
// UIBarButtonItemをセット
self.navigationItem.setLeftBarButtonItems([leftNavEditButtonItem], animated: true)
}
class MyViewController: UIViewController {
var rightNavEditButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(MyViewController.test))
func test() {
print("hogehoge")
}
func occurSomeEvent(_ calendar: FSCalendar, didSelect date: Date) {
self.navigationItem.setRightBarButtonItems([rightNavEditButtonItem!], animated: true)
}
}
class MyViewController: UIViewController {
var rightNavEditButtonItem : UIBarButtonItem?
override func viewDidLoad() {
rightNavEditButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(MyViewController.test))
}
func test() {
print("hogehoge")
}
func occurSomeEvent(_ calendar: FSCalendar, didSelect date: Date) {
self.navigationItem.setRightBarButtonItems([rightNavEditButtonItem!], animated: true)
}
}