IOS OpenInActivity Mono
需要要在UIActivityViewController Action栏中加入一个OpenInActivity.
原先其实就是在原先的基础上将OpenIn 整合进来。
创建一个OpenInActivity继承与UIActivity。
复写三个关键属性 :
1. Title: 显示活动的名称
2. Image: 显示活动的图标
3. Type: 可重复使用的名称 "com.xxx.activity.openin"
复写三个关键方法:
1. bool CanPerform(NSObject[] activityItems) :方法返回Bool对传入的activityItems进行判断,返回是否显示此Activity。
2. Prepare(NSObject[] activityItems): 当CanPerform方法通过后会被调用,准备的代码放在这里,一般是对url的处理
3. Perform(): 当前Activty被点击时会触发的方法
方法生命周期:
.. CanPerform => Prepare() => Perform() ..
实现过程:
判断文件格式是否支持
将传入Url用 List<NSUrl>存储起来
调用Open In方法所使用对象 UIDocumentInteractionController讲文件打开
因为手机上UIActivityViewController展示方式不同,所以需要加以判断,IPad通过UIBarButtonItem将它Popover出来,IPhone 则是直接Present。
所以在实例化对象时,根据设备不同而传入UIBarButtonItem或superView。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 var openInAppActivity = new OpeninActivity (this.View, actionButton); 2 var fileUrl = NSUrl.FromFilename (GetReportPath()); 3 var objs = new NSObject[]{ fileUrl }; 4 var activitys = new UIActivity[]{ openInAppActivity }; 5 6 var excludedActivityTypes = new NSString[] { 7 UIActivityType.PostToWeibo, 8 UIActivityType.Message, 9 UIActivityType.PostToTwitter, 10 UIActivityType.PostToFacebook, 11 UIActivityType.CopyToPasteboard, 12 }; 13 14 UIActivityViewController avc = new UIActivityViewController (objs, activitys); 15 avc.ExcludedActivityTypes = excludedActivityTypes; 16 17 openInAppActivity.ActivityDelegate = new OpenInAppActivityDelegate (); 18 if (UIUserInterfaceIdiom.Phone == UIDevice.CurrentDevice.UserInterfaceIdiom) { 19 openInAppActivity.SuperViewController = avc; 20 this.PresentViewController (avc, true, null); 21 } else { 22 if (activityPopoverController == null) 23 activityPopoverController = new UIPopoverController (avc); 24 openInAppActivity.SuperViewController = this.activityPopoverController; 25 this.activityPopoverController.PresentFromBarButtonItem (actionButton, UIPopoverArrowDirection.Any, true); 26 }
最终效果:
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class OpeninActivity:UIActivity, IUIDocumentInteractionControllerDelegate, IUIActionSheetDelegate 2 { 3 public readonly NSString OpenInActivityType = new NSString("com.pasasoft.activity.Openin"); 4 5 private List<NSUrl> fileURLs; 6 private CGRect rect; 7 private UIBarButtonItem barButtonItem; 8 private UIView superView; 9 private UIDocumentInteractionController docController; 10 11 public OpenInAppActivityDelegate ActivityDelegate; 12 13 public NSObject SuperViewController{ get; set;} 14 15 public override NSString Type { 16 get { 17 return OpenInActivityType; 18 } 19 } 20 21 public override string Title { 22 get { 23 return "Open In"; 24 } 25 } 26 27 public override UIImage Image { 28 get { 29 return UIImage.FromBundle (ImageFiles.OpenIn); 30 } 31 } 32 33 public OpeninActivity(UIView view, CGRect rect):base() 34 { 35 this.superView = view; 36 this.rect = rect; 37 } 38 39 public OpeninActivity(UIView view, UIBarButtonItem barButtonItem):base() 40 { 41 this.superView = view; 42 this.barButtonItem = barButtonItem; 43 } 44 45 public override bool CanPerform (NSObject[] activityItems) 46 { 47 int count = 0; 48 foreach (var item in activityItems) { 49 if (item.IsKindOfClass(new Class(typeof(NSUrl))) && ((NSUrl)item).IsFileUrl) 50 count++; 51 } 52 53 return (count >= 1); 54 } 55 56 public override void Prepare (NSObject[] activityItems) 57 { 58 List<NSUrl> nsurls = new List<NSUrl> (); 59 foreach (var item in activityItems) { 60 if (item.IsKindOfClass(new Class(typeof(NSUrl))) && ((NSUrl)item).IsFileUrl) { 61 nsurls.Add (((NSUrl)item)); 62 } 63 // if (item.IsKindOfClass(new Class(typeof(UIImage)))) { 64 // 65 // } 66 } 67 this.fileURLs = nsurls; 68 } 69 70 public override void Perform () 71 { 72 if (this.SuperViewController == null) { 73 this.Finished (true); 74 return; 75 } 76 77 if (this.SuperViewController.RespondsToSelector (new Selector ("dismissPopoverAnimated"))) { 78 ((UIPopoverController)SuperViewController).Dismiss (true); 79 ((UIPopoverController)SuperViewController).Delegate.DidDismiss ((UIPopoverController)this.SuperViewController); 80 presentOpenIn (); 81 } else if ((this.SuperViewController as UIPopoverController)?.ContentViewController != null) { 82 ((UIPopoverController)this.SuperViewController).Dismiss (true); 83 presentOpenIn (); 84 } else { 85 presentOpenIn (); 86 } 87 } 88 89 private void presentOpenIn() 90 { 91 if (fileURLs.Count > 1) { 92 this.openSelectFileActionSheet (); 93 } else { 94 this.openDocumentInteractionControllerWithFileURL (this.fileURLs.Last()); 95 } 96 } 97 98 #region Helper 99 100 private string UTIForURL(NSUrl url) 101 { 102 CFString UTI = UTType.CreatePreferredIdentifier (UTType.TagClassFilenameExtension, url.PathExtension, null); 103 return UTI.ToString (); 104 } 105 106 private void openDocumentInteractionControllerWithFileURL(NSUrl fileURL) 107 { 108 this.docController = new UIDocumentInteractionController (); 109 docController.Url = fileURL; 110 docController.WeakDelegate = this; 111 docController.Uti = this.UTIForURL (fileURL); 112 bool success; 113 if (UIUserInterfaceIdiom.Phone == UIDevice.CurrentDevice.UserInterfaceIdiom) { 114 success = this.docController.PresentOpenInMenu (CGRect.Empty, this.superView, true); 115 } else { 116 if (this.barButtonItem != null) { 117 success = docController.PresentOpenInMenu (this.barButtonItem, true); 118 } else { 119 success = this.docController.PresentOpenInMenu (CGRect.Empty, this.superView, true); 120 } 121 } 122 123 if (!success) { 124 string deviceType = UIDevice.CurrentDevice.LocalizedModel; 125 string message = "Your " + deviceType + " doesn't seem to have any other Apps installed that can open this document."; 126 string title = "No suitable App installed"; 127 AlertHelper.ShowAlert (title, message); 128 this.Finished (false); 129 } 130 131 } 132 133 public void DismissDocumentInteractionControllerAnimated(bool animated) 134 { 135 this.docController.DismissMenu (animated); 136 137 this.Finished (false); 138 } 139 140 private void openSelectFileActionSheet() 141 { 142 UIActionSheet actionSheet = new UIActionSheet ("Select a file"); 143 actionSheet.WeakDelegate = this; 144 145 foreach (var url in this.fileURLs) { 146 actionSheet.AddButton (url.LastPathComponent); 147 } 148 149 actionSheet.CancelButtonIndex = actionSheet.AddButton ("Cancel"); 150 151 152 if (UIUserInterfaceIdiom.Phone == UIDevice.CurrentDevice.UserInterfaceIdiom) { 153 actionSheet.ShowFrom (CGRect.Empty, this.superView, true); 154 } else { 155 if (this.barButtonItem != null) { 156 actionSheet.ShowFrom (this.barButtonItem, true); 157 } else { 158 actionSheet.ShowFrom (rect, this.superView, true); 159 } 160 } 161 } 162 163 #endregion 164 165 #region UIDocumentInteractionControllerDelegate 166 167 [Export ("documentInteractionControllerWillPresentOpenInMenu:")] 168 public void WillPresentOpenInMenu (UIDocumentInteractionController controller) 169 { 170 if (this.ActivityDelegate.RespondsToSelector (new Selector ("OpenInAppActivityWillPresentDocumentInteractionController"))) { 171 this.ActivityDelegate.OpenInAppActivityDidDismissDocumentInteractionController (this); 172 } 173 } 174 175 [Export ("documentInteractionControllerDidDismissOpenInMenu:")] 176 public void DidDismissOpenInMenu (UIDocumentInteractionController controller) 177 { 178 if (this.ActivityDelegate.RespondsToSelector (new Selector ("OpenInAppActivityDidDismissDocumentInteractionController"))) { 179 this.ActivityDelegate.OpenInAppActivityDidDismissDocumentInteractionController (this); 180 } 181 } 182 183 [Export ("documentInteractionController:didEndSendingToApplication:")] 184 public void DidEndSendingToApplication (UIDocumentInteractionController controller, string application) 185 { 186 if (this.ActivityDelegate.RespondsToSelector (new Selector ("OpenInAppActivityDidEndSendingToApplication"))) { 187 this.ActivityDelegate.OpenInAppActivityDidEndSendingToApplication (this); 188 }else if (this.ActivityDelegate.RespondsToSelector (new Selector ("OpenInAppActivityDidSendToApplication"))) { 189 this.ActivityDelegate.OpenInAppActivityDidSendToApplication (application); 190 } 191 192 this.Finished (true); 193 } 194 195 #endregion 196 197 #region Action sheet delegate 198 199 [Export ("actionSheet:didDismissWithButtonIndex:")] 200 public void Dismissed (UIActionSheet actionSheet, nint buttonIndex) 201 { 202 if (buttonIndex != actionSheet.CancelButtonIndex) { 203 this.openDocumentInteractionControllerWithFileURL (this.fileURLs[(int)buttonIndex]); 204 } else { 205 this.Finished (false); 206 } 207 } 208 209 #endregion 210 211 #region Image conversion 212 213 private void localFileURLForImage(UIImage image) 214 { 215 216 } 217 218 #endregion 219 } 220 221 public class OpenInAppActivityDelegate:NSObject 222 { 223 public virtual void OpenInAppActivityWillPresentDocumentInteractionController(OpeninActivity activity){} 224 public virtual void OpenInAppActivityDidDismissDocumentInteractionController(OpeninActivity activity){} 225 public virtual void OpenInAppActivityDidEndSendingToApplication(OpeninActivity activity){} 226 public virtual void OpenInAppActivityDidSendToApplication(string application){} 227 }