UIActivityViewController的使用

UIActivityViewController的使用#

UIActivityViewController是iOS上為App實現(xiàn)多種服務(wù)的一個標(biāo)準(zhǔn)視圖控制器,系統(tǒng)默認(rèn)提供了很多的標(biāo)準(zhǔn)服務(wù)病附,如拷貝鏈接,添加到Safari閱讀列表隙赁,還有就是多平臺的分享墨礁,包括微博充石,F(xiàn)acebook,email等峻厚。其實看起來就是一個actionSheet响蕴。

我們的任務(wù)是負(fù)責(zé)配置、顯示和關(guān)閉這個視圖控制器目木,配置也就是為這個視圖控制器提供數(shù)據(jù)源换途。當(dāng)然,我們也可以根據(jù)需要自定義自己服務(wù)(通過繼承UIActivity)刽射。在iPad上军拟,我們以popover的形式顯示這個視圖控制器;而在 iPhone 和 iPod touch上, 我們需要以模態(tài)的形式顯示誓禁。

先寫一個最基本的代碼:

    let image = UIImage(named: "iOS9")
    let str = "hello iOS9"
    let url = NSURL(string: "http://helloseed.io")
    let items:[AnyObject] = [image!, str, url!];
    
    self.presentViewController(vc, animated: true, completion: nil)
標(biāo)準(zhǔn)顯示

可以看到懈息,幾句代碼就可以顯示出我們需要的controller了。Activity分為兩類摹恰,圖中可以看到它被分割線分為上下兩部分辫继,上面部分為Share(Objective-C為UIActivityCategoryShare)類型,下面部分為Action(Objective-C為UIActivityCategoryAction)類型。

下面我們添加如下代碼:

    vc.completionWithItemsHandler = {(activityType:String?, completed:Bool, returnedItems:[AnyObject]?, activityError:NSError?) -> Void in
        if completed {
            self.alert("成功")
        }
        vc.completionWithItemsHandler = nil
    }

然后點擊其中的一個item俗慈,這時會彈出成功的alert姑宽。沒錯,這個block屬性就是用來處理點擊后的回調(diào)闺阱。

結(jié)果回調(diào)

幾個參數(shù)說明:activityType為被點擊的服務(wù)類型炮车;completed標(biāo)識服務(wù)是否執(zhí)行成功;returnedItems是一個包含NSExtensionItem對象的數(shù)組;activityError指出出錯原因瘦穆。更詳細(xì)的參數(shù)說明可以參考官方文檔

現(xiàn)在纪隙,我們再在調(diào)用presentViewController方法之前添加一行代碼:

    vc.excludedActivityTypes = [UIActivityTypeMail, UIActivityTypeAddToReadingList, UIActivityTypeAssignToContact];

再次運行,可以發(fā)現(xiàn)少了Mail扛或、Assign to Contact绵咱、Add to Reading List這三個item。是的熙兔,excludedActivityTypes這個數(shù)組就是用來指定不需要那些服務(wù)的悲伶。我們可以將不需要的服務(wù)寫進(jìn)數(shù)組內(nèi),具體還有哪些服務(wù)黔姜,見文檔拢切。(注:現(xiàn)在所運行的環(huán)境都是在iOS8上的,iOS9后還添加了Notes(備忘錄)秆吵,和Reminders(提醒事項)這兩個服務(wù))

取消顯示不必要是item

標(biāo)準(zhǔn)的基本上就這些,然并卵五慈。纳寂。。
基本上泻拦,僅使用系統(tǒng)默認(rèn)提供的服務(wù)是不夠的毙芜,每個App有自己的需求,所以自定義服務(wù)是必然的争拐。前面說到腋粥,通過繼承UIActivity來實現(xiàn)自定義,下面來自定義幾個常用的服務(wù):微信Timeline架曹,微信Session隘冲、新浪微博、拷貝鏈接绑雄。(這里就以微博和拷貝鏈接為例展辞,其他都大同小異的)

  1. 先創(chuàng)建一個類名為:CustomActivity,繼承于UIActivity万牺,以后其他自定義的Activity類直接繼承它罗珍。代碼如下:
import UIKit

class CustomActivity: UIActivity {
    var title:String?
    var image:UIImage?
    var url:NSURL?
    
    override class func activityCategory() -> UIActivityCategory {
        return .Share
    }
    
    override func activityType() -> String? {
        return NSStringFromClass(self.classForCoder)
    }
    
    /**
    返回是否可以執(zhí)行
    
    - parameter activityItems: 從調(diào)用處傳進(jìn)來的items,可以通過這個items里面存放的類型數(shù)據(jù)來判斷是否可以執(zhí)行
    
    - returns: 返回true脚粟,則這個activity就會在controller上出現(xiàn)覆旱;否則,則不會出現(xiàn)
    */
    override func canPerformWithActivityItems(activityItems: [AnyObject]) -> Bool {
        //只要items有數(shù)據(jù)核无,就返回true扣唱。
        if activityItems.count > 0 {
            return true
        }
        return false
    }
    
    /**
    準(zhǔn)備數(shù)據(jù)
    
    - parameter activityItems: 數(shù)據(jù)對象數(shù)組
    */
    override func prepareWithActivityItems(activityItems: [AnyObject]) {
        for activityItem in activityItems {
            if let title = activityItem as? String {
                self.title = title
            } else if let image = activityItem as? UIImage {
                self.image = image
            } else if let url = activityItem as? NSURL {
                self.url = url
            }
        }
    }
    
    /**
    執(zhí)行點擊
    */
//    override func performActivity() {
//        super.performActivity()

//        print(self.title)
//        print(self.image)
//        print(self.url)
//    }
}

幾個需要我們override的方法的作用已經(jīng)在注釋上說明,就不多說了。
接著画舌,我們創(chuàng)建一個WeiboActivity堕担,如下:

import UIKit

class WeiboActivity: CustomActivity {
    override func activityTitle() -> String? {
        return "新浪微博"
    }
    
    override func activityImage() -> UIImage? {
        return UIImage(named: "weibo")
    }
    
    override func performActivity() {
        super.performActivity()
        
        //將需要分享的數(shù)據(jù)通過微博SDK進(jìn)行分析
        
    }
}

然后創(chuàng)建一個CopyLinkActivity類,如下:

import UIKit

class CopyLinkActivity: CustomActivity {
    override class func activityCategory() -> UIActivityCategory {
        return .Action
    }
    
    override func activityTitle() -> String? {
        return "拷貝鏈接"
    }
    
    override func activityImage() -> UIImage? {
        return UIImage(named: "share_link")
    }
    
    override func canPerformWithActivityItems(activityItems: [AnyObject]) -> Bool {
    //因為是拷貝鏈接曲聂,所有如果不存在NSURL對象霹购,則返回false
        for item in activityItems {
            if let _ = item as? NSURL {
                return true
            }
        }
        return false
    }
    
    override func performActivity() {
        super.performActivity()
        //拷貝需要的鏈接
    }
}

自定義工作告一段落,現(xiàn)在回到ViewController朋腋,將代碼改成如下:

    let image = UIImage(named: "seed")
    let str = "hello iOS9"
    let url = NSURL(string: "http://helloseed.io")
    let items:[AnyObject] = [image!, str, url!];

    let weibo = WeiboActivity()     //實例化WeiboActivity
    let copylink = CopyLinkActivity()   //實例化CopyLinkActivity

    let vc = UIActivityViewController(activityItems: items, applicationActivities: [weibo, copylink])
    vc.excludedActivityTypes = [UIActivityTypeMail, UIActivityTypeAddToReadingList, UIActivityTypeAssignToContact];
    self.presentViewController(vc, animated: true, completion: nil)

    vc.completionWithItemsHandler = {(activityType:String?, completed:Bool, returnedItems:[AnyObject]?, activityError:NSError?) -> Void in
        if completed {
            self.alert("成功")
        }
        vc.completionWithItemsHandler = nil
    }

執(zhí)行程序:


自定義Activity

順利完成齐疙。不過我們發(fā)現(xiàn),點擊自定義的activity后旭咽,不會調(diào)用completionWithItemsHandler方法贞奋,即沒有彈出成功。我的解決方法是穷绵,同樣自定義一個closure(Objective-C中的block)來執(zhí)行回調(diào)轿塔。于是,在CustomActivity中添加:

    var finishedBlock:(()-> Void)?

并將上面注釋掉的方法performActivity解注釋仲墨。如下:

    /**
    執(zhí)行點擊
    */
    override func performActivity() {
        super.performActivity()
        
        if let block = self.finishedBlock {
            block()
        }
        
        self.activityDidFinish(true)
    }

這樣勾缭,在調(diào)用處想執(zhí)行什么代碼直接添加到finishedBlock即可。
再啰嗦一下目养,其實我們可以連prepareWithActivityItems都不需要override俩由,title,image,url也都不需要定義,CustomActivity的子類也不需要overrideperformActivity了癌蚁。直接將要執(zhí)行的代碼放到finishedBlock上幻梯,類似這樣:

    /**
    執(zhí)行點擊
    */
    override func performActivity() {
        super.performActivity()
        
        if let block = self.finishedBlock {
            block()
        }
        
        self.activityDidFinish(true)
    }

最后,為Activity提供的圖片需要注意的一點:如果Activity的Category是Share努释,則不能是透明的碘梢,即關(guān)閉透明通道;如果Category是Action洽洁,則圖片需要開啟透明通道痘系,因為系統(tǒng)需要將圖片渲染成和標(biāo)準(zhǔn)的一樣顏色(所以,不需要將圖片顏色調(diào)成一致饿自,系統(tǒng)會幫我們做)汰翠,另外,圓角也是系統(tǒng)處理的昭雌。

Demo: https://github.com/linshaolie/UIActivityViewControllerDemo

參考文章:
https://github.com/nixzhu/dev-blog/blob/master/2014-04-22-ui-activity-viewcontroller.md

想獲得第一手精彩文章复唤,歡迎關(guān)注我的微信公眾號:"iOS和Android干貨"

掃一掃發(fā)現(xiàn)更多精彩文章
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市烛卧,隨后出現(xiàn)的幾起案子佛纫,更是在濱河造成了極大的恐慌妓局,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呈宇,死亡現(xiàn)場離奇詭異好爬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)甥啄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門存炮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜈漓,你說我怎么就攤上這事穆桂。” “怎么了融虽?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵享完,是天一觀的道長。 經(jīng)常有香客問我有额,道長般又,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任巍佑,我火速辦了婚禮倒源,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘句狼。我一直安慰自己,他們只是感情好热某,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布腻菇。 她就那樣靜靜地躺著,像睡著了一般昔馋。 火紅的嫁衣襯著肌膚如雪筹吐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天秘遏,我揣著相機(jī)與錄音丘薛,去河邊找鬼。 笑死邦危,一個胖子當(dāng)著我的面吹牛洋侨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播倦蚪,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼希坚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了陵且?” 一聲冷哼從身側(cè)響起裁僧,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后聊疲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茬底,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年获洲,在試婚紗的時候發(fā)現(xiàn)自己被綠了阱表。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡昌妹,死狀恐怖捶枢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情飞崖,我是刑警寧澤烂叔,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站固歪,受9級特大地震影響蒜鸡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牢裳,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一逢防、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蒲讯,春花似錦忘朝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晦墙,卻和暖如春悦昵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晌畅。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工但指, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抗楔。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓棋凳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谓谦。 傳聞我的和親對象是個殘疾皇子贫橙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容