首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当向视图控制器以外的对象分配委托时未调用的SFSafariViewControllerDelegate方法

当向视图控制器以外的对象分配委托时未调用的SFSafariViewControllerDelegate方法
EN

Stack Overflow用户
提问于 2016-03-28 23:50:50
回答 2查看 5.7K关注 0票数 7

我有一个简单的视图控制器,当点击链接按钮时,它会显示一个SFSafariViewController。

代码语言:javascript
复制
#import "ViewController.h"
#import "SafariDelegate.h"

@interface ViewController ()

@property(nonatomic, strong) NSString *url;
@property(nonatomic, weak) SafariDelegate *safariDelegate;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.url = @"http://www.google.com";
}

- (IBAction)linkTapped:(id)sender {
    SFSafariViewController *vc = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:self.url]];
    SafariDelegate *safariDelegate = [[SafariDelegate alloc] init];
    vc.delegate = safariDelegate;
    [self presentViewController:vc animated:YES completion:nil];
}

@end

SafariDelegate符合SFSafariViewControllerDelegate,只在委托方法触发时记录。

SafariDelegate.h

代码语言:javascript
复制
#import <Foundation/Foundation.h>
#import <SafariServices/SafariServices.h>

@interface SafariDelegate : NSObject <SFSafariViewControllerDelegate>

@end

SafariDelegate.m

代码语言:javascript
复制
#import "SafariDelegate.h"

@implementation SafariDelegate

- (NSArray<UIActivity *> *)safariViewController:(SFSafariViewController *)controller activityItemsForURL:(NSURL *)URL     title:(nullable NSString *)title
{
    NSLog(@"safariViewController activityItemsForURL");

    return @[];
}

- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller
{
    NSLog(@"safariViewControllerDidFinish");
}


- (void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully
{
    NSLog(@"safariViewController didCompleteInitialLoad");
}

@end

当我点击按钮时,Safariview控制器正确地加载页面,但是从来不调用委托方法(包括我点击‘Done’时)。我在显示'vc‘的行上放置了一个断点,并确认委托在该点上被正确设置。我遗漏了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-28 23:59:41

SafariViewController不保留它的委托,所以在linkTapped:方法返回后它会立即被释放,因为没有其他方法对它有很强的引用。

你需要在某个地方保留一个有力的参考资料。您可能只需将当前视图控制器中的属性更改为strong并将其存储在那里即可。您还可以将其保存在safari视图控制器上的关联对象中。

票数 6
EN

Stack Overflow用户

发布于 2019-03-29 07:15:38

同样的问题也发生在我身上。我创建了“函数内部的SafariViewController”。因此,SafariViewController内存被清除。所以,我无法从SafariViewControllerDelegate获得触发器。

最后我找到了一个解决这个问题的方法。

当您在类中创建SFSafariViewController时。必须将其声明为全局变量。

代码语言:javascript
复制
class Foo: NSObject {
    var safariVC: SFSafariViewController!
}

然后,您可以分配您的SafariViewController。

代码语言:javascript
复制
func config(_ loadUrl: URL) {

   if #available(iOS 11.0, *) {
       let config = SFSafariViewController.Configuration()
       config.barCollapsingEnabled = true
       config.entersReaderIfAvailable = true
       safariVC = SFSafariViewController(url: loadUrl, configuration: config)
   } else {
      // Fallback on earlier versions
      safariVC = SFSafariViewController(url: loadUrl)
   }
}

然后设置一个委托

代码语言:javascript
复制
self.safariVC.delegate = self

最后给出了safariViewController。

代码语言:javascript
复制
 UIApplication.shared.keyWindow?.rootViewController?.present(safariVC, animated: true, completion: nil)

现在肯定会触发safariViewController委托。

代码语言:javascript
复制
// MARK: - SFSafariViewControllerDelegate
extension Foo: SFSafariViewControllerDelegate {

    func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
        print("SafariVC is dismissed")
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36273134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档