diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index b94336f3..b2039b91 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -107,6 +107,8 @@ D6C693CF216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693CE216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift */; }; D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; }; D6C693F92162E4DB007D6A6D /* StatusContentLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */; }; + D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */; }; + D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */; }; D6C94D852139DFD800CB5196 /* LargeImage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6C94D842139DFD800CB5196 /* LargeImage.storyboard */; }; D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D862139E62700CB5196 /* LargeImageViewController.swift */; }; D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D882139E6EC00CB5196 /* AttachmentView.swift */; }; @@ -285,6 +287,8 @@ D6C693CE216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPermissionTableViewCell.swift; sourceTree = ""; }; D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerNavigationDelegate.swift; sourceTree = ""; }; D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentLabel.swift; sourceTree = ""; }; + D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingViewController.swift; sourceTree = ""; }; + D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Children.swift"; sourceTree = ""; }; D6C94D842139DFD800CB5196 /* LargeImage.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LargeImage.storyboard; sourceTree = ""; }; D6C94D862139E62700CB5196 /* LargeImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageViewController.swift; sourceTree = ""; }; D6C94D882139E6EC00CB5196 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = ""; }; @@ -456,6 +460,7 @@ D641C780213DD7C4004B4513 /* Screens */ = { isa = PBXGroup; children = ( + D6C693FA2162FE5D007D6A6D /* Utilities */, D641C782213DD7F0004B4513 /* Main */, D641C783213DD7FE004B4513 /* Onboarding */, D641C781213DD7DD004B4513 /* Timeline */, @@ -664,6 +669,15 @@ path = "Silent Action Permissions"; sourceTree = ""; }; + D6C693FA2162FE5D007D6A6D /* Utilities */ = { + isa = PBXGroup; + children = ( + D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */, + D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */, + ); + path = Utilities; + sourceTree = ""; + }; D6D4DDC3212518A000E1C4BB = { isa = PBXGroup; children = ( @@ -1086,10 +1100,12 @@ D6C693CA2161253F007D6A6D /* SilentActionPermissionsTableViewController.swift in Sources */, D6333B372137838300CE884A /* AttributedString+Trim.swift in Sources */, D641C777213CAA9E004B4513 /* ActionNotificationTableViewCell.swift in Sources */, + D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */, D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */, D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */, D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */, D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */, + D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */, D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */, D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */, D663626A2136163000C9CBA2 /* PreferencesAdaptive.swift in Sources */, diff --git a/Tusker/Screens/Profile/ProfileTableViewController.swift b/Tusker/Screens/Profile/ProfileTableViewController.swift index 0708bcb9..fc34c899 100644 --- a/Tusker/Screens/Profile/ProfileTableViewController.swift +++ b/Tusker/Screens/Profile/ProfileTableViewController.swift @@ -43,13 +43,8 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive { if MastodonCache.account(for: accountID) != nil { updateAccountUI() } else { - let activityIndicator = UIActivityIndicatorView(style: .whiteLarge) - activityIndicator.color = .darkGray - activityIndicator.startAnimating() - activityIndicator.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(activityIndicator) - activityIndicator.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor) - activityIndicator.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor) + let loadingVC = LoadingViewController() + add(loadingVC) MastodonCache.account(for: accountID) { (account) in guard account != nil else { let alert = UIAlertController(title: "Something Went Wrong", message: "Couldn't load the selected account", preferredStyle: .alert) @@ -62,11 +57,12 @@ class ProfileTableViewController: UITableViewController, PreferencesAdaptive { return } DispatchQueue.main.async { - activityIndicator.removeFromSuperview() + loadingVC.remove() self.updateAccountUI() self.tableView.reloadData() } } + } } diff --git a/Tusker/Screens/Utilities/LoadingViewController.swift b/Tusker/Screens/Utilities/LoadingViewController.swift new file mode 100644 index 00000000..e2196e75 --- /dev/null +++ b/Tusker/Screens/Utilities/LoadingViewController.swift @@ -0,0 +1,38 @@ +// +// LoadingViewController.swift +// Tusker +// +// Created by Shadowfacts on 10/1/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import UIKit + +// Based on John Sundell's example: https://www.swiftbysundell.com/posts/using-child-view-controllers-as-plugins-in-swift +class LoadingViewController: UIViewController { + + private var activityIndicator: UIActivityIndicatorView! + + override func viewDidLoad() { + super.viewDidLoad() + + activityIndicator = UIActivityIndicatorView(style: .whiteLarge) + activityIndicator.color = .darkGray + activityIndicator.translatesAutoresizingMaskIntoConstraints = false + + view.addSubview(activityIndicator) + + activityIndicator.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true + activityIndicator.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor).isActive = true + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + // 0.5s delay so indicator is not shown if data loads very quickly + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + self?.activityIndicator.startAnimating() + } + } + +} diff --git a/Tusker/Screens/Utilities/UIViewController+Children.swift b/Tusker/Screens/Utilities/UIViewController+Children.swift new file mode 100644 index 00000000..743e2349 --- /dev/null +++ b/Tusker/Screens/Utilities/UIViewController+Children.swift @@ -0,0 +1,25 @@ +// +// UIViewController+Children.swift +// Tusker +// +// Created by Shadowfacts on 10/1/18. +// Copyright © 2018 Shadowfacts. All rights reserved. +// + +import UIKit + +extension UIViewController { + func add(_ child: UIViewController) { + addChild(child) + view.addSubview(child.view) + child.didMove(toParent: self) + } + + func remove() { + guard parent != nil else { return } + + willMove(toParent: nil) + removeFromParent() + view.removeFromSuperview() + } +}