Slide 1

Slide 1 text

Drag and Drop CA.swift #3 2017/06/19 Keisuke Tatsumi

Slide 2

Slide 2 text

Keisuke Tatsumi • iOS engineer at AbemaTV, Inc. • Github, Qiita : cokaholic • Twitter : @TK_u_nya • AppStore : Keisuke Tatsumi • WWDC 2017 attendee
 ʢMy First Time! ʣ

Slide 3

Slide 3 text

ຊ೔ͷςʔϚ͸…

Slide 4

Slide 4 text

Drag and Drop

Slide 5

Slide 5 text

Agenda • What’s Drag and Drop • How To Use • Draggable Items in the Same Screen • Summary

Slide 6

Slide 6 text

Agenda • What’s Drag and Drop • How To Use • Draggable Items in the Same Screen • Summary

Slide 7

Slide 7 text

What’s Drag and Drop • iOS11ͷ৽ػೳ

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

iPhone5 iPhone5c

Slide 10

Slide 10 text

What’s Drag and Drop • iOS11ͷ৽ػೳ • ύιίϯͰͷυϥοά&υϩοϓͱಉ͡Πϯλ ϥΫγϣϯͰΞϓϦؒͰσʔλΛड͚౉͠Ͱ ͖Δ

Slide 11

Slide 11 text

What’s Drag and Drop • iOS11ͷ৽ػೳ • ύιίϯͰͷυϥοά&υϩοϓͱಉ͡Πϯλ ϥΫγϣϯͰΞϓϦؒͰσʔλΛड͚౉͠Ͱ ͖Δ • iPadͰͷΈ࢖͑Δ

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

ͱ͜Ζ͕…

Slide 14

Slide 14 text

iPhoneͰ΋࢖͑ΔͬΆ͍ʁ

Slide 15

Slide 15 text

iPhoneͰ΋࢖͑ΔͬΆ͍ʁ • ݱࡏʢ2017.6.19ʣ·Ͱʹ഑෍͞Ε͍ͯΔiOS11 betaͰ΋ɺಈըͷ௨Γਖ਼͘͠ػೳ͢Δ • ΋ͱ΋ͱAppleࣾ಺Ͱ͸iPhoneͰ΋ςετ͞Εͯ ͍ΔػೳΒ͍͠ • ΋͔ͨ͠͠Βɺਖ਼ࣜϦϦʔε൛Ͱ΋iPhone্Ͱ࢖ ͑Δ͔΋

Slide 16

Slide 16 text

What’s Drag and Drop • iOS11ͷ৽ػೳ • ύιίϯͰͷυϥοά&υϩοϓͱಉ͡Πϯλ ϥΫγϣϯͰΞϓϦؒͰσʔλΛड͚౉͠Ͱ ͖Δ • iPadͰͷΈ࢖͑ΔʢiPhoneͰ΋Մʁʣ

Slide 17

Slide 17 text

Agenda • What’s Drag and Drop • How To Use • Draggable Items in the Same Screen • Summary

Slide 18

Slide 18 text

How To Use • APIͷྲྀΕ͸େ͖̏ͭ͘ͷηΫγϣϯʹ෼͔ΕΔ ‣ ϦϑτηΫγϣϯʢ্࣋ͪ͛Δʣ ‣ υϥοάηΫγϣϯʢಈ͔͢ʣ ‣ υϩοϓηΫγϣϯʢམͱ͢ʣ API Roadmap

Slide 19

Slide 19 text

How To Use • ·ͣ͸લஈ֊Ͱ͋ΔViewͱͷ઀ଓΛߦ͏ API Roadmap

Slide 20

Slide 20 text

How To Use import UIKit class ViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! override func viewDidLoad() { super.viewDidLoad() // υϥοά&υϩοϓ͢Δʹ͸༗ޮʹ͢Δඞཁ͕͋Δ imageView.isUserInteractionEnabled = true // UIImageViewʹυϥοάΠϯλϥΫγϣϯΛ௥Ճ͢Δ let dragInteraction = UIDragInteraction(delegate: self) imageView.addInteraction(dragInteraction) // ViewControllerͷviewʹυϩοϓΠϯλϥΫγϣϯΛ௥Ճ͢Δ let dropInteraction = UIDropInteraction(delegate: self) view.addInteraction(dropInteraction) } } ViewController.swift ᶃViewͱͷ઀ଓ

Slide 21

Slide 21 text

ϦϑτηΫγϣϯ ্࣋ͪ͛Δ

Slide 22

Slide 22 text

ϦϑτηΫγϣϯ import UIKit extension ViewController: UIDragInteractionDelegate { // required // υϥοά͕࢝·ͬͨࡍʹݺ͹ΕΔ func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { guard let image = imageView.image else { return [] } // NSItemProviderʹૹΔΦϒδΣΫτ(NSItemProviderWriting)ΛೖΕΔ // ࠓճ͸imageViewʹදࣔ͞Ε͍ͯΔը૾ΛೖΕΔ let provider = NSItemProvider(object: image) // provider͔ΒUIDragItemΛੜ੒͠ɺ഑ྻʹͯ͠ฦ͢ let item = UIDragItem(itemProvider: provider) return [item] } } ViewController+Drag.swift ᶄUIDragInteractionDelegateͷ࣮૷Λߦ͏

Slide 23

Slide 23 text

υϥοάηΫγϣϯ ಈ͔͢

Slide 24

Slide 24 text

υϥοάηΫγϣϯ import UIKit extension ViewController: UIDragInteractionDelegate { // required // υϥοά͕࢝·ͬͨࡍʹݺ͹ΕΔ func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { guard let image = imageView.image else { return [] } // NSItemProviderʹૹΔΦϒδΣΫτ(NSItemProviderWriting)ΛೖΕΔ // ࠓճ͸imageViewʹදࣔ͞Ε͍ͯΔը૾ΛೖΕΔ let provider = NSItemProvider(object: image) // provider͔ΒUIDragItemΛੜ੒͠ɺ഑ྻʹͯ͠ฦ͢ let item = UIDragItem(itemProvider: provider) return [item] } } ViewController+Drag.swift ᶄUIDragInteractionDelegateͷ࣮૷Λߦ͏

Slide 25

Slide 25 text

υϥοάηΫγϣϯ import UIKit extension ViewController: UIDragInteractionDelegate { // required // υϥοά͕࢝·ͬͨࡍʹݺ͹ΕΔ func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { guard let image = imageView.image else { return [] } // NSItemProviderʹૹΔΦϒδΣΫτ(NSItemProviderWriting)ΛೖΕΔ // ࠓճ͸imageViewʹදࣔ͞Ε͍ͯΔը૾ΛೖΕΔ let provider = NSItemProvider(object: image) // provider͔ΒUIDragItemΛੜ੒͠ɺ഑ྻʹͯ͠ฦ͢ let item = UIDragItem(itemProvider: provider) return [item] } } ViewController+Drag.swift ͳʹ͜Εʁ ᶄUIDragInteractionDelegateͷ࣮૷Λߦ͏

Slide 26

Slide 26 text

NSItemProviderWriting • υϥοά&υϩοϓػೳͷυϥοάͷࡍʹ౉͢ΦϒδΣΫτ ͷॻ͖ࠐΈ༻Ϋϥε • ॻ͖ࠐΉ͜ͱ͕Ͱ͖ΔΫϥε͸جຊతʹ͸Լهͷ̑ͭ ‣ NSString ‣ NSAttributedString ‣ NSURL ‣ UIColor ‣ UIImage

Slide 27

Slide 27 text

υϩοϓηΫγϣϯ མͱ͢

Slide 28

Slide 28 text

υϩοϓηΫγϣϯ import UIKit import MobileCoreServices // UTCoreTypesΛ࢖༻͢Δࡍʹඞཁ extension ViewController: UIDropInteractionDelegate { // υϩοϓ͞ΕΔΞΠςϜ͕༗ޮ͔Ͳ͏͔൑ఆ͢Δࡍʹݺ͹ΕΔ func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool { // ૹΒΕͯ͘ΔΞΠςϜͷ൑ఆ͸UTIͰߦ͏ // kUTTypeImage͸ը૾ͷ৔߹ͷidentifierͰɺUTI͸ public.image ͱͳΔ // ͜ͷ৔߹ɺը૾Ͱ͋ΓɺૹΒΕ͖ͯͨΞΠςϜ਺͕̍ͭͷ৔߹ͷΈ௨͢ͱ͍͏ҙຯʹͳΔ return session.hasItemsConforming(toTypeIdentifiers: [kUTTypeImage as String]) && session.items.count == 1 } } ViewController+Drop.swift ᶅUIDropInteractionDelegateͷ࣮૷Λߦ͏

Slide 29

Slide 29 text

υϩοϓηΫγϣϯ // υϥοάதʹҐஔ͕มΘΔͨͼʹݺ͹ΕΔ func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal { // υϥοάதͷΞΠςϜͷ࠲ඪ let dropLocation = session.location(in: view) let operation: UIDropOperation if imageView.frame.contains(dropLocation) { // imageViewͷதͰ཭ͨ͠৔߹ɺίϐʔѻ͍ʹͳΔ operation = .copy } else { // ͦΕҎ֎ͷҐஔͰ཭ͨ͠৔߹ɺΩϟϯηϧ͞ΕΔ operation = .cancel } return UIDropProposal(operation: operation) } ViewController+Drop.swift ᶅUIDropInteractionDelegateͷ࣮૷Λߦ͏

Slide 30

Slide 30 text

υϩοϓηΫγϣϯ // υϥοάதʹҐஔ͕มΘΔͨͼʹݺ͹ΕΔ func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal { // υϥοάதͷΞΠςϜͷ࠲ඪ let dropLocation = session.location(in: view) let operation: UIDropOperation if imageView.frame.contains(dropLocation) { // imageViewͷதͰ཭ͨ͠৔߹ɺίϐʔѻ͍ʹͳΔ operation = .copy } else { // ͦΕҎ֎ͷҐஔͰ཭ͨ͠৔߹ɺΩϟϯηϧ͞ΕΔ operation = .cancel } return UIDropProposal(operation: operation) } ViewController+Drop.swift ᶅUIDropInteractionDelegateͷ࣮૷Λߦ͏ UIDropOperationʁ

Slide 31

Slide 31 text

UIDropOperation • ΞΠςϜΛͦͷҐஔͰυϩοϓͨ͠ࡍͷڍಈ ͕Ͳ͏ͳΔ͔ΛϢʔβʔʹࣔ͢͜ͱ͕Ͱ͖Δ

Slide 32

Slide 32 text

υϩοϓηΫγϣϯ // υϩοϓ͕֬ఆͨ͋͠ͱɺड͚औͬͨσʔλͷϩʔυ։࢝࣌ʹݺ͹ΕΔ func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) { // ηογϣϯ͔Βड͚औͬͨը૾Λϩʔυ͢Δ session.loadObjects(ofClass: UIImage.self) { [weak self] imageItems in guard let images = imageItems as? [UIImage] else { return } // ड͚औͬͨը૾ΛimageViewʹηοτ͢Δ self?.imageView.image = images.first } } } ViewController+Drop.swift ᶅUIDropInteractionDelegateͷ࣮૷Λߦ͏

Slide 33

Slide 33 text

υϩοϓηΫγϣϯ // υϩοϓ͕֬ఆͨ͋͠ͱɺड͚औͬͨσʔλͷϩʔυ։࢝࣌ʹݺ͹ΕΔ func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) { // ηογϣϯ͔Βड͚औͬͨը૾Λϩʔυ͢Δ session.loadObjects(ofClass: UIImage.self) { [weak self] imageItems in guard let images = imageItems as? [UIImage] else { return } // ड͚औͬͨը૾ΛimageViewʹηοτ͢Δ self?.imageView.image = images.first } } } ViewController+Drop.swift ᶅUIDropInteractionDelegateͷ࣮૷Λߦ͏ ͜͜·ͰͰυϥοά&υϩοϓ͸׬੒

Slide 34

Slide 34 text

Agenda • What’s Drag and Drop • How To Use • Draggable Items in the Same Screen • Summary

Slide 35

Slide 35 text

Draggable Items in the Same Screen • υϥοάηΫγϣϯʹ͓͍ͯɺυϥοάͰ͖ ΔΞΠςϜ͕ಉҰը໘಺ʹ̎ͭҎ্͋Δ৔߹ɺ ͲͷΑ͏ʹͯ͠൑ఆ͢Δ͔Λߟ͑ͯΈͨ

Slide 36

Slide 36 text

import UIKit extension ViewController: UIDragInteractionDelegate { // required // υϥοά͕࢝·ͬͨࡍʹݺ͹ΕΔ func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { guard let image = imageView.image else { return [] } // NSItemProviderʹૹΔΦϒδΣΫτ(NSItemProviderWriting)ΛೖΕΔ // ࠓճ͸imageViewʹදࣔ͞Ε͍ͯΔը૾ΛೖΕΔ let provider = NSItemProvider(object: image) // provider͔ΒUIDragItemΛੜ੒͠ɺ഑ྻʹͯ͠ฦ͢ let item = UIDragItem(itemProvider: provider) return [item] } } ViewController+Drag.swift ϫϯύλʔϯͰ͔͠౉ͤͳ͍ʁ ઌ΄Ͳͷ࣮૷ͩͱ… Draggable Items in the Same Screen

Slide 37

Slide 37 text

Draggable Items in the Same Screen import UIKit extension ViewController: UIDragInteractionDelegate { // required // υϥοά͕࢝·ͬͨࡍʹݺ͹ΕΔ func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { // interaction.viewͰυϥοά͞Ε͍ͯΔView͕Θ͔Δʂ guard let interactionView = interaction.view else { return [] } let provider: NSItemProvider // ͋ͱ͸ɺViewͰ൑ఆ͢Ε͹υϥοά͞Ε͍ͯΔUIImageViewͰ౉͢ը૾Λม͑ΒΕΔʂ if interactionView.isEqual(imageView) { guard let image = imageView.image else { return [] } provider = NSItemProvider(object: image) } else if interactionView.isEqual(imageView2) { guard let image = imageView2.image else { return [] } provider = NSItemProvider(object: image) } else { return [] } let item = UIDragItem(itemProvider: provider) return [item] } } ViewController+Drag.swift

Slide 38

Slide 38 text

Draggable Items in the Same Screen import UIKit extension ViewController: UIDragInteractionDelegate { // required // υϥοά͕࢝·ͬͨࡍʹݺ͹ΕΔ func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { // interaction.viewͰυϥοά͞Ε͍ͯΔView͕Θ͔Δʂ guard let interactionView = interaction.view else { return [] } let provider: NSItemProvider // ͋ͱ͸ɺViewͰ൑ఆ͢Ε͹υϥοά͞Ε͍ͯΔUIImageViewͰ౉͢ը૾Λม͑ΒΕΔʂ if interactionView.isEqual(imageView) { guard let image = imageView.image else { return [] } provider = NSItemProvider(object: image) } else if interactionView.isEqual(imageView2) { guard let image = imageView2.image else { return [] } provider = NSItemProvider(object: image) } else { return [] } let item = UIDragItem(itemProvider: provider) return [item] } } ViewController+Drag.swift

Slide 39

Slide 39 text

Draggable Items in the Same Screen import UIKit extension ViewController: UIDragInteractionDelegate { // required // υϥοά͕࢝·ͬͨࡍʹݺ͹ΕΔ func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] { // interaction.viewͰυϥοά͞Ε͍ͯΔView͕Θ͔Δʂ guard let interactionView = interaction.view else { return [] } let provider: NSItemProvider // ͋ͱ͸ɺViewͰ൑ఆ͢Ε͹υϥοά͞Ε͍ͯΔUIImageViewͰ౉͢ը૾Λม͑ΒΕΔʂ if interactionView.isEqual(imageView) { guard let image = imageView.image else { return [] } provider = NSItemProvider(object: image) } else if interactionView.isEqual(imageView2) { guard let image = imageView2.image else { return [] } provider = NSItemProvider(object: image) } else { return [] } let item = UIDragItem(itemProvider: provider) return [item] } } ViewController+Drag.swift

Slide 40

Slide 40 text

Demo

Slide 41

Slide 41 text

Agenda • What’s Drag and Drop • How To Use • Draggable Items in the Same Screen • Summary

Slide 42

Slide 42 text

Summary • υϥοάˍυϩοϓ͸iOS11͔Βͷ৽ػೳͰ iPad ΋͘͠͸ iPhone Ͱ࢖༻Ͱ͖Δ • υϥοάˍυϩοϓʹ͸Ϧϑτɺυϥοάɺ υϩοϓͷ̏ͭͷηΫγϣϯ͕͋Δ • υϥοάˍυϩοϓ͸ಉҰը໘಺ʹෳ਺ͷυ ϥοάՄೳͳΞΠςϜ͕͋ͬͯ΋൑ఆͰ͖Δ

Slide 43

Slide 43 text

Demo Source https://github.com/cokaholic/DragAndDropDemo

Slide 44

Slide 44 text

Thank youʂ

Slide 45

Slide 45 text

ࢀߟϦϯΫ • iOS11Ͱ͸iPhoneͰ΋υϥοάˍυϩοϓ͕Մೳʙ։ൃऀ͕ ൃݟ
 http://iphone-mania.jp/news-171425/ • Introducing Drag and Drop - WWDC 2017
 https://developer.apple.com/videos/play/wwdc2017/203/ • Data Delivery with Drag and Drop - WWDC 2017
 https://developer.apple.com/videos/play/wwdc2017/227/