実現したいこと
UIActivityから画像を保存したい。
わからないこと
imageの取得の仕方。
こちらのサイトを参考に複数画像をスワイプでページングさせる機能を作成しました。
そのスワイプで表示させている画像をUIActivityで保存させたいのですが、imageViewを使っていないのでimageのシュットクの仕方がわからず困ってしまいました。
@IBAction private func onTapShareButton(_ sender: Any) {}
のところをご教示いただきたいです。
##ソース
swift
1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet private weak var mainScrollView: UIScrollView! 6 @IBOutlet private weak var pageControl: UIPageControl! 7 8 var imageUrls: [URL]! 9 10 /// 現在のページインデックス 11 private var currentPage = 0 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 setupPageControl() 16 } 17 18 override func viewDidLayoutSubviews() { 19 super.viewDidLayoutSubviews() 20 setupMainScrollView() 21 (0..<imageUrls.count).forEach { page in 22 let subScrollView = generateSubScrollView(at: page) 23 mainScrollView.addSubview(subScrollView) 24 let imageView = generateImageView(at: page) 25 subScrollView.addSubview(imageView) 26 } 27 } 28 29 private func setupPageControl() { 30 pageControl.numberOfPages = imageUrls.count 31 pageControl.currentPage = currentPage 32 // タップされたときのイベントハンドリングを設定 33 pageControl.addTarget( 34 self, 35 action: #selector(didValueChangePageControl), 36 for: .valueChanged 37 ) 38 } 39 40 private func setupMainScrollView() { 41 mainScrollView.delegate = self 42 mainScrollView.isPagingEnabled = true 43 mainScrollView.showsVerticalScrollIndicator = false 44 mainScrollView.showsHorizontalScrollIndicator = false 45 // コンテンツ幅 = ページ数 x ページ幅 46 mainScrollView.contentSize = CGSize( 47 width: calculateX(at: imageUrls.count), 48 height: mainScrollView.bounds.height 49 ) 50 } 51 52 private func generateSubScrollView(at page: Int) -> UIScrollView { 53 let frame = calculateSubScrollViewFrame(at: page) 54 let subScrollView = UIScrollView(frame: frame) 55 56 subScrollView.delegate = self 57 subScrollView.maximumZoomScale = 3.0 58 subScrollView.minimumZoomScale = 1.0 59 subScrollView.showsHorizontalScrollIndicator = false 60 subScrollView.showsVerticalScrollIndicator = false 61 62 // ダブルタップされたときのイベントハンドリングを設定 63 let gesture = UITapGestureRecognizer(target: self, action: #selector(didDoubleTapSubScrollView(_:))) 64 gesture.numberOfTapsRequired = 2 65 subScrollView.addGestureRecognizer(gesture) 66 67 return subScrollView 68 } 69 70 private func generateImageView(at page: Int) -> UIImageView { 71 let frame = mainScrollView.bounds 72 let imageView = UIImageView(frame: frame) 73 74 imageView.contentMode = .scaleAspectFill 75 imageView.clipsToBounds = true 76 imageView.loadimage(url: imageUrls[page]) 77 78 return imageView 79 } 80 81 /// ページコントロールを操作された時 82 @objc private func didValueChangePageControl() { 83 currentPage = pageControl.currentPage 84 let x = calculateX(at: currentPage) 85 mainScrollView.setContentOffset(CGPoint(x: x, y: 0), animated: true) 86 } 87 88 /// サブスクロールビューがダブルタップされた時 89 @objc private func didDoubleTapSubScrollView(_ gesture: UITapGestureRecognizer) { 90 guard let subScrollView = gesture.view as? UIScrollView else { return } 91 92 if subScrollView.zoomScale < subScrollView.maximumZoomScale { 93 // タップされた場所を中心に拡大する 94 let location = gesture.location(in: subScrollView) 95 let rect = calculateRectForZoom(location: location, scale: subScrollView.maximumZoomScale) 96 subScrollView.zoom(to: rect, animated: true) 97 } else { 98 subScrollView.setZoomScale(subScrollView.minimumZoomScale, animated: true) 99 } 100 } 101 102 /// ページ幅 x position でX位置を計算 103 private func calculateX(at position: Int) -> CGFloat { 104 return mainScrollView.bounds.width * CGFloat(position) 105 } 106 107 /// スクロールビューのオフセット位置からページインデックスを計算 108 private func calculatePage(of scrollView: UIScrollView) -> Int { 109 let width = scrollView.bounds.width 110 let offsetX = scrollView.contentOffset.x 111 let position = (offsetX - (width / 2)) / width 112 return Int(floor(position) + 1) 113 } 114 115 /// タップされた位置と拡大率から拡大後のCGRectを計算する 116 private func calculateRectForZoom(location: CGPoint, scale: CGFloat) -> CGRect { 117 let size = CGSize( 118 width: mainScrollView.bounds.width / scale, 119 height: mainScrollView.bounds.height / scale 120 ) 121 let origin = CGPoint( 122 x: location.x - size.width / 2, 123 y: location.y - size.height / 2 124 ) 125 return CGRect(origin: origin, size: size) 126 } 127 128 /// サブスクロールビューのframeを計算 129 private func calculateSubScrollViewFrame(at page: Int) -> CGRect { 130 var frame = mainScrollView.bounds 131 frame.origin.x = calculateX(at: page) 132 return frame 133 } 134 135 private func resetZoomScaleOfSubScrollViews(without exclusionSubScrollView: UIScrollView) { 136 for subview in mainScrollView.subviews { 137 guard 138 let subScrollView = subview as? UIScrollView, 139 subScrollView != exclusionSubScrollView 140 else { 141 continue 142 } 143 subScrollView.setZoomScale(subScrollView.minimumZoomScale, animated: false) 144 } 145 } 146 147 148@IBAction private func onTapShareButton(_ sender: Any) { 149 // ここがわからない 150 } 151} 152 153extension ViewController: UIScrollViewDelegate { 154 155 func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 156 if scrollView != mainScrollView { return } 157 158 let page = calculatePage(of: scrollView) 159 if page == currentPage { return } 160 currentPage = page 161 162 pageControl.currentPage = page 163 164 // 他のすべてのサブスクロールビューの拡大率をリセット 165 resetZoomScaleOfSubScrollViews(without: scrollView) 166 } 167 168 func viewForZooming(in scrollView: UIScrollView) -> UIView? { 169 return scrollView.subviews.first as? UIImageView 170 } 171 172 func scrollViewDidZoom(_ scrollView: UIScrollView) { 173 guard let imageView = scrollView.subviews.first as? UIImageView else { return } 174 175 scrollView.contentInset = UIEdgeInsets( 176 top: max((scrollView.frame.height - imageView.frame.height) / 2, 0), 177 left: max((scrollView.frame.width - imageView.frame.width) / 2, 0), 178 bottom: 0, 179 right: 0 180 ) 181 } 182}
あなたの回答
tips
プレビュー