Swift 5 - 用户第二次单击标签栏按钮后,需要帮助在视图控制器 1 上重新加载 Web 视图
Posted
技术标签:
【中文标题】Swift 5 - 用户第二次单击标签栏按钮后,需要帮助在视图控制器 1 上重新加载 Web 视图【英文标题】:Swift 5 - Need help reloading web view on view controller 1 after user clicks tab bar button for the second time 【发布时间】:2021-03-14 20:05:50 【问题描述】:在过去的一周里,我已经被这个问题困扰了 30 多个小时,试图弄清楚这一点,但似乎无法做到这一点。我有一个 Swift 5 ios 应用程序。它有一个带有 3 个标签/视图控制器的标签栏视图控制器。我所有的代码都存储在一个视图控制器文件中。下面是标签栏和第一个视图控制器的代码,所有其他视图控制器的结构都类似。
预期:当用户在选项卡上单击两次时,我们会将他们单击的次数存储在名为 VariableRefresh 的变量中。当该变量变为 2 时,我们将刷新视图控制器上的 Web 视图。
当我为视图控制器 1 单击两次选项卡栏时,会触发调试打印消息,它告诉我两次单击选项卡栏是成功的,但 Web 视图没有刷新。我收到错误消息说 web 视图返回 nil 并使其成为可选值。所以我补充说?到网络视图使其成为可选值,但问题是网络视图仍然为零,并且它不会刷新/重新加载。当用户按两次标签栏时应该调用func reload,它应该在视图控制器1 func reload()中执行函数。
import GoogleMobileAds
import UIKit
import SwiftUI
import FBAudienceNetwork
import WebKit
//we will use this to identifiy if two click are made on this tab, we will put if then statement to monitor clicks and if 2 taps ont he tab, then we will refresh the view controller 1 webview.
var VariableRefresh = 0
//variable for url
let url1 = URL(string:"http://tesla1.social-goat.com")
//variable for url request
let request = URLRequest(url: url1!)
class TabBarClass: UITabBarController, UITabBarControllerDelegate, WKNavigationDelegate
override func viewDidLoad()
super.viewDidLoad()
debugPrint("Message - TabBarClass - viewDidLoad")
self.delegate = self
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController)
let selectedIndex = tabBarController.viewControllers?.firstIndex(of: viewController)!
if selectedIndex == 0
debugPrint("Message - loaded func tabBarController")
VariableRefresh += 1
if VariableRefresh == 2
let sendValue = ViewController1();
sendValue.reload()
//################ view controller 1 - Groups START
class ViewController1: UIViewController,FBAdViewDelegate
let url1 = URL(string:"http://tesla1.social-goat.com")
//
@IBOutlet var webView1: WKWebView!
@IBOutlet weak var bannerView_home: GADBannerView!
override func viewDidLoad()
super.viewDidLoad()
//moved request to the parent level so that viewcontroller1 and tab bar view controller can access
// let request = URLRequest(url: url1!)
debugPrint("Message - viewDidLoad")
//load request for webview
webView1.load(request)
//allow webvie to have back and forward browsing function by swip left or right
webView1.allowsBackForwardNavigationGestures = true
webView1.navigationDelegate = self
webView1.isUserInteractionEnabled = true
//banner id ca-app-pub-8404457641397226/8691324688
//test banner id ca-app-pub-3940256099942544/2435281174
// Replace this ad unit ID with your own ad unit ID.
bannerView_home.adUnitID = "ca-app-pub-8404457641397226/8691324688"
bannerView_home.rootViewController = self
//lets load the admob banner
loadBannerAd()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
//this will be called from tab bar view, the problem here is that webview will come up as nil. putting ? or ! still does not reload the webview.
func reload()
webView1.load(request)
override func viewWillAppear(_ animated: Bool)
debugPrint("Viewwillapper")
let request = URLRequest(url: url1!)
//reload webview when you navigate back to the view controller 1 tab
webView1.load(request)
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(animated)
// Note loadBannerAd is called in viewDidAppear as this is the first time that
// the safe area is known. If safe area is not a concern (eg your app is locked
// in portrait mode) the banner can be loaded in viewDidLoad.
override func viewWillTransition(
to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
)
coordinator.animate(alongsideTransition: _ in
self.loadBannerAd()
)
func loadBannerAd()
// Here safe area is taken into account, hence the view frame is used after the
// view has been laid out.
let frame = () -> CGRect in
if #available(iOS 11.0, *)
return view.frame.inset(by: view.safeAreaInsets)
else
return view.frame
()
let viewWidth = frame.size.width
// Here the current interface orientation is used. If the ad is being preloaded
// for a future orientation change or different orientation, the function for the
// relevant orientation should be used.
bannerView_home.adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth)
bannerView_home.load(GADRequest())
//################ view controller 1 - Groups END
【问题讨论】:
【参考方案1】:当你调用 let sendValue = ViewController1();您创建了与您的实现断开连接的视图控制器的全新实例。尝试替换 let sendValue = ViewController1();让 sendValue = tabBarController.viewControllers[0] 作为 ViewController1!在您的标签栏控制器类中。然后你应该可以调用 sendValue.reload()。我第一次尝试从不同的类调用 reload 时错过了。
【讨论】:
您好,Marko,感谢您的回复。我将 func reload() webView1.load(request) 替换为 With func reload() webView1.load(request) webView1.allowsBackForwardNavigationGestures = true webView1.navigationDelegate = self webView1.isUserInteractionEnabled = true 而且我仍然得到一个 nil 错误“致命错误:意外发现 nil同时为 webView.load(request) 隐式展开 Optional"。我想要做的是当用户单击选项卡按钮两次时,它将重新加载 web 视图。我想用我的 3 个选项卡按钮中的每一个来执行此操作,如果用户在第一个选项卡上,然后按两次选项卡 1,那么它应该重新加载 webview。 我正在重读你的答案,所以你是说我应该直接从标签栏控制器类调用 webView1.load(request) 吗?如果是这样,我将如何做到这一点,因为 Web 视图位于视图控制器 1 类上。我试图在标签栏类上创建一个 IB 连接,但是当我从视图控制器 1 上的 Web 视图中拖动一个连接并尝试将其拖到标签栏类时,它不会让我在标签栏类中删除 Web 视图的连接。 我现在将您的代码复制/粘贴到代码编辑器中,以便更清楚地看到您想要实现的目标。当您调用let sendValue = ViewController1();
时,您将创建与您的实现断开连接的视图控制器的全新实例。尝试在标签栏控制器类中将let sendValue = ViewController1();
替换为let sendValue = tabBarController.viewControllers[0] as ViewController1!
。然后你应该可以打电话给sendValue.reload()
。我第一次错过了你尝试从不同的类调用 reload。
天啊谢谢谢谢MARKO!!!!你是最好的!对不起,我很兴奋地喊出你为我工作,更重要的是,你让我学到了一些关于“创建的 viewcontroller1 的新实例”的新知识。我从来不知道会发生这种情况,现在我正在对此进行更多研究。非常感谢再次感谢!!干杯! :)以上是关于Swift 5 - 用户第二次单击标签栏按钮后,需要帮助在视图控制器 1 上重新加载 Web 视图的主要内容,如果未能解决你的问题,请参考以下文章