Я новый Swift разработчик реализует основные части Safari с WKWebView (мне нужно взаимодействовать между Javascript & Swift, поэтому SFSafariViewController не вариант), и я пытаюсь объявить все элементы программным путем.Swift 3, IOS, 10 - программно объявлены UIStackView не фитинга ширину экрана
Для имитации поиска бар и прогресс бар Safari, я хочу, чтобы установить UISearchBar, сложенные на вершине UIProgressView, как titleView
для UIViewController «s UINavigationItem. Я могу управлять им только одним элементом, но не со стеком из двух элементов.
Вот как выглядит мой проект прямо сейчас. UISearchBar и UIProgressView либо слишком широкие или слишком тонкие, чтобы заполнить UINavigationBar должным образом, в зависимости от вращения:
Вот мой код ViewController.swift:
import WebKit
import UIKit
class ViewController: UIViewController, WKNavigationDelegate, UISearchBarDelegate {
var searchBar: UISearchBar = UISearchBar()
var progressView: UIProgressView = UIProgressView(progressViewStyle: .bar)
var stackView: UIStackView = UIStackView()
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
/** Watches for changes in the WKWebView.estimatedProgress variable, and */
webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)
/** Initialise toolbar elements */
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let refresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: webView, action: #selector(webView.reload))
toolbarItems = [spacer, refresh]
navigationController?.isToolbarHidden = false
/** Initialise the UISearchBar */
searchBar.delegate = self // not clear yet whether setting this is necessary.
searchBar.searchBarStyle = UISearchBarStyle.minimal
searchBar.showsCancelButton = true
searchBar.widthAnchor.constraint(equalToConstant: (navigationController?.navigationBar.bounds.width)!).isActive = true
// searchBar.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
// searchBar.sizeToFit()
/** Initialise the UIProgressView */
progressView.widthAnchor.constraint(equalToConstant: (navigationController?.navigationBar.bounds.width)!).isActive = true
// progressView.heightAnchor.constraint(equalToConstant: 4.0).isActive = true
// progressView.sizeToFit()
/** Add the UISearchBar & UIProgressView to the UIStackView, then initialise it and finally set it as the UINavigationItem's titleView.*/
stackView.axis = UILayoutConstraintAxis.vertical
stackView.alignment = UIStackViewAlignment.center
stackView.distribution = UIStackViewDistribution.fillProportionally
stackView.addArrangedSubview(searchBar)
stackView.addArrangedSubview(progressView)
stackView.translatesAutoresizingMaskIntoConstraints = false;
/* These two constraints are causing a crash, so disabling them for now. */
// stackView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
// stackView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
navigationItem.titleView = stackView
navigationController?.hidesBarsOnSwipe = true
let url = URL(string: "https://en.wikipedia.org")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
}
/** Updates the UIProgressView. */
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// keyPath "estimatedProgress" is equivalent to #keyPath(WKWebView.estimatedProgress)
if keyPath == "estimatedProgress" {
// progressView.isHidden = webView.estimatedProgress == 1 // if we want to hide upon 100%
progressView.progress = Float(webView.estimatedProgress)
}
}
/** Sets the webView's title upon navigation finishing. */
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
title = webView.title
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Примечание: любое принятое решение должно продолжаться до отобразите стек элементов правильно после обратного вызова, чтобы скрыть UINavigationBar, инициированный navigationController?.hidesBarsOnSwipe
, т.е. когда пользователь выполняет жестовый салфет на WKWebView.