Как отобразить Safari из UIView?


#1

Здравствуйте.
Есть всплывающий UIView на весь экран телефона, в нем есть кнопка, как по нажатию на нее отобразить Safari?
Стандартный вариант

            let url = URL(string: "http://www.yandex.ru")
            let vc = SFSafariViewController(url: url!)
            self.present(vc, animated: true, completion: nil)

понятно не работает.


#2

Почему не работает? Появляется ошибка?


#3

Да, ошибка Value of type 'PlayerDetailsView' has no member 'present', PlayerDetailsView имеет класс UIView


#4

Тогда все легко и просто. У вас 2 выбора

  1. Создать делегат в вашем View и при клике на кнопку вызывать метод из делегата, который и запустит показ Safari из вашего VC
  2. Передавать в ваше View ссылку на VC, только ссылка должна быть weak и тогда вы сможете сделать так vcReference.present(…)

#5

Буду разбираться, спасибо за наводку. Хотя, что первый, что второй вариант пока для меня темный лес. Какой вариант предпочтительней и от чего зависит выбор варианта решения?


#6

Зачем так сложно? А что мешает открыть вместо вью на весь экран новый контроллер?


#7

UIView имеет свойство сворачиваться на часть экрана и разворачиваться, поэтому Controller не подходит


#8

Вопрос в иерархии.Так что это вообще не аргумент)


#9

Разве можно Controller, который вместо UIView, свернуть на часть экрана и пользоваться приложением, переходя на другие экраны, не закрывая свернутый Controller?


#10

Я предложил решение исходя из текущей реализации.


#11

Поступил я следующим образом, не знаю насколько это правильно или нет, но оно работает

 guard let urlString = "myLink" else { return }
        if urlString != "" {
            let url = URL(string: urlString)
            let vc = SFSafariViewController(url: url!)
            vc.delegate = self
            UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
        }

#12

Сейчас другая проблема: если указывать адрес, который получаю от пользователя, без http или любой произвольный текст, приложение падает, так как SFSafariViewController не может обработать эту ссылку. Как сделать проверку на корректность полученной ссылки, если адрес некорректен, то не выполнять метод SFSafariViewController?


#13

Изучить более базовые темы. Вы слишком спешите. У Вас в коде прямо сказано, что вы хотите, чтобы приложение упало, если такой ссылки нет. Темы про опционально и их извлечение.


#14

@Quaes Спасибо за уточнение. Почитал, изучил. Теперь код работает как надо

 @IBAction func linkTapped(_ sender: UIButton) {
        let urlString = "linkFromUser"
        if isValidUrl(urlString: urlString) == true {
            print("Can open URL:", urlString)
            let url = URL(string: urlString)
            let safariVC = SFSafariViewController(url: url!)
            safariVC.delegate = self
            UIApplication.shared.keyWindow?.rootViewController?.present(safariVC, animated: true, completion: nil)
        } else {
            print("Can't open URL:", urlString)
        }
    }
    
    func isValidUrl (urlString: String?) -> Bool {
        if let urlString = urlString {
            if let url = URL(string: urlString) {
                return UIApplication.shared.canOpenURL(url)
            }
        }
        return false
    }