How to get UIActivityIndicator to disappear once appearing? - xcode

I currently have my app linking to a certain URL upon opening the app, and this obviously can have a delay between opening it and the webView actually loading, so I want it to display an activity indicator whenever the webView is loading, I have the following code in my ViewController.swift:
class ViewController: UIViewController, UIWebViewDelegate {
#IBOutlet weak var webView: UIWebView!
#IBOutlet weak var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
let url = URL(string: "url to site")
webView.loadRequest(URLRequest(url: url!)
}
func webViewDidStartLoad(webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView){
activityIndicator.stopAnimating()
}
The activity indicator shows up from the beginning but it does not disappear once the webView loads and stays their forever.

The way you have your code organized is a bit confusing. It appears you are declaring your funcs inside the #IBAction function. If this is the case, this will not work.
Try this instead
class ViewController: UIViewController, UIWebviewDelegate {
override func viewDidLoad() {
...
webView.delegate = self
// You should add this to your Storyboard, above the webview instead of here in the code
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
// I forget the actual method name - look it up
view.insertSubview(activityIndicator, above: webView)
}
#IBAction func openButton(_ sender: Any) {
let url = URL(string: "websiteURL")
webView.loadRequest(URLRequest(url: url!))
}
func webViewDidStartLoad(webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(webView: UIWebView){
activityIndicator.stopAnimating()
}
// You'll also want to add the "didFail" method
}

The issue is a syntax issue, you have to add an underscore in the functions.
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
let url = URL(string: "your URL")
webView.loadRequest(URLRequest(url: url!))
}
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool{
activityIndicator.startAnimating()
return true
}
func webViewDidStartLoad(_ webView: UIWebView){
activityIndicator.startAnimating()
}
func webViewDidFinishLoad(_ webView: UIWebView){
activityIndicator.stopAnimating()
}
func webView(_ webView: UIWebView, didFailLoadWithError error: Error){
activityIndicator.stopAnimating()
}

Related

Only instance methods can be declared #IBAction | XCODE ERROR | Swift 5

Here's my code do not suggest to remove IBAction I'm a beginner making a browser. I'm also
pretty new to this program:
import Cocoa
import WebKit
class ViewController: NSViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
}
}
#IBAction func didEnterKeyTapped( sender: NSTextField){
let urlString = sender.stringValue
guard let url = URL(string: urlString) else {return}
let urlRequest = URLRequest(url: url)
webView.load(urlRequest)
#IBAction func didnavigationButtonTapped ( sender: NSSegmentedControl){
if sender.selectedSegment == 0 {
webView.goBack()
}else {
webView.Forward()
}
}
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
let currentUrl = webView.url?.absoluteString ?? ""
guard let windowController = view.window?.windowController as? WindowController else {return}
let textField = windowController.urlTextField
textField?.stringValue = currentUrl
}
}
}
You declared the #IBActions outside of the ViewController class. An IBAction must be a member of a class. Move the IBActions inside the class to fix the compiler error.
Another problem in your code is you declared the didNavigationButtonTapped IBAction inside the didEnterKeyTapped IBAction. The two IBActions should be separate functions, such as the following:
#IBAction func didEnterKeyTapped( sender: NSTextField){
let urlString = sender.stringValue
guard let url = URL(string: urlString) else {return}
let urlRequest = URLRequest(url: url)
webView.load(urlRequest)
}
#IBAction func didnavigationButtonTapped ( sender: NSSegmentedControl) {
if sender.selectedSegment == 0 {
webView.goBack()
}else {
webView.Forward()
}
}

webView didFinish Navigation never gets called

I am trying to get the splash view ( back_button ) to remove itself once the webpage fully loads, I had done quite a bit of researching and they always point to the same code as an answer. However, mine will not get called. Can somebody advise what I am doing wrong?
import UIKit
import WebKit
class ViewController: UIViewController {
#IBOutlet weak var LoadingView: UIImageView!
var webView: WKWebView?
var bgImage: UIImageView?
var imageViewObject :UIImageView?
override func viewDidLoad() {
super.viewDidLoad()
//var imageViewObject :UIImageView
let screenSize: CGRect = UIScreen.main.bounds
imageViewObject = UIImageView(frame:CGRect(x:0,y: 0, width: screenSize.width, height: screenSize.height))
imageViewObject?.image = UIImage(named:"back_image")
webView?.navigationDelegate = self as? WKNavigationDelegate
self.view.addSubview(imageViewObject!)
let myURL = URL(string: "https://www.google.com")
let myRequest = URLRequest(url: myURL!)
_ = webView?.load(myRequest)
}
override func loadView() {
super.loadView()
//self.view.sendSubview(toBack: imageViewObject)
//self.view = self.LoadingView
self.webView = WKWebView()
self.view = self.webView
}
#IBAction func BackButton(_ sender: Any) {
if(webView?.canGoBack)!
{
webView?.goBack();
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("TEST")
imageViewObject?.removeFromSuperview()
}
func webViewDidFinishLoad(webView: WKWebView) {
imageViewObject?.removeFromSuperview()
self.view = self.webView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
you have to conform to it's protocol delegate by putting this line of code in viewDidLoad
webView?.uiDelegate = self
after doing that , now if you want to use delegation method's you have to put your viewController as a subclass of UIWebViewDelegate
class ViewController: UIViewController ,UIWebViewDelegate{
I fixed this by making
webView?.navigationDelegate = self
and adding this to the Class
class ViewController: UIViewController, WKNavigationDelegate

swift 4- Save the last data of a text field in a label so that they are displayed when the app is restarted

I have a problem, I want to create a small app in which data in a formula can be charged.
Currently the data from three ViewControllers and one PickerViewController will be given back to the first ViewController.
That works very well too.
Now I want that the data at the start not on "nil" set but have a certain value.
Thereafter, the data entered last should reappear when the app is restarted.
I would like to apologize for my english, it is not my preferred language ...
Here is a part of my code how I wrote it
Main ViewController:
import UIKit
class RecivingViewController: UIViewController, SendDataBack, SendDataBack2, SendDataBack3, SendDataBack4 {
#IBOutlet weak var recivingData: UILabel!
#IBOutlet weak var recivingData2: UILabel!
#IBOutlet weak var recivingData3: UILabel!
#IBOutlet weak var recivingData4: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func userData(data: String) {
recivingData.text = data
}
func userData2(data: String) {
recivingData2.text = data
}
func userData3(data: String) {
recivingData3.text = data
}
func PickerData(data: String){
recivingData4.text = data
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "view1" {
let SendingVC: SendingViewController = segue.destination as! SendingViewController
SendingVC.delegate = self
}
if segue.identifier == "view2" {
let SendingVC2: Sending2ViewController = segue.destination as! Sending2ViewController
SendingVC2.delegate = self
}
if segue.identifier == "view3" {
let SendingVC3: Sending3ViewController = segue.destination as! Sending3ViewController
SendingVC3.delegate = self
}
if segue.identifier == "picker" {
let SendingVC4: PickerViewController = segue.destination as! PickerViewController
SendingVC4.delegate = self
}
}
}
one of the other ViewControllers:
import UIKit
protocol SendDataBack {
func userData(data: String)
}
class SendingViewController: UIViewController {
#IBOutlet weak var DataTxt: UITextField!
var delegate: SendDataBack? = nil
#IBAction func done(_ sender: Any) {
if delegate != nil {
if DataTxt.text != nil {
let data = DataTxt.text
delegate?.userData(data: data!)
dismiss(animated: true, completion: nil)
}
}
}
In order to see data after app is restarted you should use user defaults.
For saving data
UserDefaults.standard.set(newValue, forKey: "data")
For loading data in your view controller, if it's first load, when data is nil
UserDefaults.standard.string(forKey: "data")

Use of unresolved identifier 'self'

I am working on a Mac OS X application with Swift.
This is my first time and I thought it would be the same as it is on iOS.
So I got this error (in the title) on this code:
import Cocoa
import AppKit
class LoginViewController: NSViewController {
#IBOutlet weak var emailTextField: NSTextField!
#IBOutlet weak var passwordTextField: NSSecureTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear() {
}
super.viewDidAppear()
if NSUserDefaults.standardUserDefaults().valueForKey("uid") != nil && CURRENT_USER!.authData != nil
{
self.logoutButton.hidden = false
}
}
func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
func loginAction(sender: AnyObject)
{
let email = self.emailTextField.text
let password = self.passwordTextField.text
...
}
}
What do I have to write instead of self?
Using self is correct. Try using the property stringValue instead of text.
Here is the code that worked for me:
#IBOutlet weak var emailTextField: NSTextField!
#IBAction func sendTapped(sender: AnyObject) {
let email = self.emailTextField.stringValue
print(email)
}

How do I fix this crash? Xcode 6 Swift

I am only coding in two features. MailComposer and WebView. But when I run my app and go to the email interface tab it crashes "fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)". When I go to the tab that displays the webview, it works fine. The Webview.loadRequest(request) is messing something up with the mail coding. But I don't know where I can put it to make both features work.
If anyone has any clue how to fix this, please let me know. Thanks.
Here is the coding for the View.Controller.Swift file...
import UIKit
import MessageUI
class ViewController: UIViewController, MFMailComposeViewControllerDelegate {
#IBOutlet weak var Webview: UIWebView!
#IBOutlet weak var Subject: UITextField!
#IBOutlet weak var Body: UITextView!
var URLPath = "http://google.com"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
loadAddressURL()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func SendEmail(sender: AnyObject) {
var SubjectText = "Inquiry:"
SubjectText += Subject.text
var MessageBody = Body
var toRecipients = ["phillip.lebsack1#gmail.com"]
var mc: MFMailComposeViewController = MFMailComposeViewController()
mc.mailComposeDelegate = self
mc.setSubject(SubjectText)
mc.setMessageBody(MessageBody.text, isHTML: false)
mc.setToRecipients(toRecipients)
self.presentViewController(mc, animated: true, completion: nil)
}
func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
switch result.value{
case MFMailComposeResultCancelled.value:
NSLog("Mail Cancelled")
case MFMailComposeResultSaved.value:
NSLog("Mail Saved")
case MFMailComposeResultSent.value:
NSLog("Mail Sent")
case MFMailComposeResultFailed.value:
NSLog("Mail Sent Failure: %#",[error.localizedDescription])
default:
break
}
self.dismissViewControllerAnimated(true, completion: nil)
}
func loadAddressURL(){
let requestURL = NSURL(string:URLPath)
let request = NSURLRequest(URL: requestURL!)
Webview.loadRequest(request)
}
}
Make sure no warning message and bind all #IBOutlet in your ViewController.

Resources