Redo app navigation/tab bar

This commit is contained in:
Shadowfacts 2019-01-05 12:59:55 -05:00
parent 656cc1d3ef
commit fe85e3c1d6
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
8 changed files with 86 additions and 180 deletions

View File

@ -57,7 +57,7 @@
D6109A0D214599E100432DC2 /* RequestRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0C214599E100432DC2 /* RequestRange.swift */; }; D6109A0D214599E100432DC2 /* RequestRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0C214599E100432DC2 /* RequestRange.swift */; };
D6109A0F21459B6900432DC2 /* Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0E21459B6900432DC2 /* Pagination.swift */; }; D6109A0F21459B6900432DC2 /* Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0E21459B6900432DC2 /* Pagination.swift */; };
D6109A11214607D500432DC2 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A10214607D500432DC2 /* Timeline.swift */; }; D6109A11214607D500432DC2 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A10214607D500432DC2 /* Timeline.swift */; };
D621544821682A9D0003D87D /* TabsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544721682A9D0003D87D /* TabsTableViewController.swift */; }; D6163F2C21AA0AF1008DAC41 /* MyProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */; };
D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544A21682AD30003D87D /* TabTableViewCell.swift */; }; D621544B21682AD30003D87D /* TabTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D621544A21682AD30003D87D /* TabTableViewCell.swift */; };
D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D621544C21682AD90003D87D /* TabTableViewCell.xib */; }; D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D621544C21682AD90003D87D /* TabTableViewCell.xib */; };
D627FF74217BBC9700CC0648 /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF73217BBC9700CC0648 /* AppRouter.swift */; }; D627FF74217BBC9700CC0648 /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF73217BBC9700CC0648 /* AppRouter.swift */; };
@ -256,7 +256,7 @@
D6109A0C214599E100432DC2 /* RequestRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestRange.swift; sourceTree = "<group>"; }; D6109A0C214599E100432DC2 /* RequestRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestRange.swift; sourceTree = "<group>"; };
D6109A0E21459B6900432DC2 /* Pagination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pagination.swift; sourceTree = "<group>"; }; D6109A0E21459B6900432DC2 /* Pagination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pagination.swift; sourceTree = "<group>"; };
D6109A10214607D500432DC2 /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = "<group>"; }; D6109A10214607D500432DC2 /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = "<group>"; };
D621544721682A9D0003D87D /* TabsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewController.swift; sourceTree = "<group>"; }; D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyProfileTableViewController.swift; sourceTree = "<group>"; };
D621544A21682AD30003D87D /* TabTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabTableViewCell.swift; sourceTree = "<group>"; }; D621544A21682AD30003D87D /* TabTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabTableViewCell.swift; sourceTree = "<group>"; };
D621544C21682AD90003D87D /* TabTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TabTableViewCell.xib; sourceTree = "<group>"; }; D621544C21682AD90003D87D /* TabTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TabTableViewCell.xib; sourceTree = "<group>"; };
D627FF73217BBC9700CC0648 /* AppRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouter.swift; sourceTree = "<group>"; }; D627FF73217BBC9700CC0648 /* AppRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouter.swift; sourceTree = "<group>"; };
@ -569,6 +569,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */, D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */,
D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */,
); );
path = Profile; path = Profile;
sourceTree = "<group>"; sourceTree = "<group>";
@ -615,7 +616,6 @@
D663626521360DD700C9CBA2 /* Preferences.storyboard */, D663626521360DD700C9CBA2 /* Preferences.storyboard */,
D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */, D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */,
D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */, D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */,
D621544721682A9D0003D87D /* TabsTableViewController.swift */,
D627FF80217FE8F400CC0648 /* BehaviorTableViewController.swift */, D627FF80217FE8F400CC0648 /* BehaviorTableViewController.swift */,
D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */, D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */,
); );
@ -1183,7 +1183,6 @@
D6434EB3215B1856001A919A /* XCBRequest.swift in Sources */, D6434EB3215B1856001A919A /* XCBRequest.swift in Sources */,
D663626221360B1900C9CBA2 /* Preferences.swift in Sources */, D663626221360B1900C9CBA2 /* Preferences.swift in Sources */,
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */, D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */,
D621544821682A9D0003D87D /* TabsTableViewController.swift in Sources */,
D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */, D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */,
04496BD721625361001F1B23 /* ContentLabel.swift in Sources */, 04496BD721625361001F1B23 /* ContentLabel.swift in Sources */,
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */, D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */,
@ -1215,6 +1214,7 @@
D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */, D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */,
D667E5E721349D4C0057A976 /* ProfileTableViewController.swift in Sources */, D667E5E721349D4C0057A976 /* ProfileTableViewController.swift in Sources */,
D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */, D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */,
D6163F2C21AA0AF1008DAC41 /* MyProfileTableViewController.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -66,6 +66,8 @@ class ComposeViewController: UIViewController {
super.init(nibName: "ComposeViewController", bundle: nil) super.init(nibName: "ComposeViewController", bundle: nil)
title = "Compose"
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelPressed)) navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelPressed))
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Drafts", style: .plain, target: self, action: #selector(draftsPressed)) navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Drafts", style: .plain, target: self, action: #selector(draftsPressed))
} }

View File

@ -8,48 +8,22 @@
import UIKit import UIKit
class MainTabBarViewController: UITabBarController { class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate {
lazy var router = AppRouter(root: self) lazy var router = AppRouter(root: self)
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
updateTabs(animated: false) self.delegate = self
}
func updateTabs(animated: Bool) { viewControllers = [
let currentTabs = Preferences.shared.tabs.filter { $1 >= 0 }.sorted { $1.1 > $0.1 }.map { $0.key } embedInNavigationController(TimelineTableViewController(for: .home, router: router)),
let viewControllers: [UIViewController] = currentTabs.map { (tab) in embedInNavigationController(NotificationsTableViewController(router: router)),
if tab == .preferences, let preferences = selectedViewController { ComposeViewController(router: router),
return preferences embedInNavigationController(TimelineTableViewController(for: .public(local: false), router: router)),
} else { embedInNavigationController(MyProfileTableViewController(router: router)),
return embedInNavigationController(createVC(for: tab)) ]
}
}
setViewControllers(viewControllers, animated: animated)
}
func createVC(for tab: Tab) -> UIViewController {
switch tab {
case .home:
return TimelineTableViewController(for: .home, router: router)
case .federated:
return TimelineTableViewController(for: .public(local: false), router: router)
case .local:
return TimelineTableViewController(for: .public(local: true), router: router)
case .myProfile:
let myProfile = ProfileTableViewController(accountID: nil, router: router)
myProfile.title = "My Profile"
MastodonController.getOwnAccount { (account) in
myProfile.accountID = account.id
}
return myProfile
case .notifications:
return NotificationsTableViewController(router: router)
case .preferences:
return PreferencesTableViewController.create()
}
} }
func embedInNavigationController(_ vc: UIViewController) -> UINavigationController { func embedInNavigationController(_ vc: UIViewController) -> UINavigationController {
@ -60,4 +34,13 @@ class MainTabBarViewController: UITabBarController {
} }
} }
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if viewController is ComposeViewController {
let compose = embedInNavigationController(ComposeViewController(router: router))
tabBarController.present(compose, animated: true)
return false
}
return true
}
} }

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.23.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="VJJ-jC-9g8"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="VJJ-jC-9g8">
<device id="retina4_7" orientation="portrait"> <device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/> <adaptation id="fullscreen"/>
</device> </device>
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.16.1"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
@ -93,7 +93,13 @@
<outlet property="delegate" destination="ArB-e7-yko" id="BFj-a8-oE6"/> <outlet property="delegate" destination="ArB-e7-yko" id="BFj-a8-oE6"/>
</connections> </connections>
</tableView> </tableView>
<navigationItem key="navigationItem" title="Preferences" id="dN7-yl-voz"/> <navigationItem key="navigationItem" title="Preferences" id="dN7-yl-voz">
<barButtonItem key="rightBarButtonItem" style="done" systemItem="done" id="k5d-0p-0Yf">
<connections>
<action selector="donePressed:" destination="ArB-e7-yko" id="6na-ww-vm4"/>
</connections>
</barButtonItem>
</navigationItem>
</tableViewController> </tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="GBL-Cz-yNZ" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="GBL-Cz-yNZ" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
@ -198,31 +204,7 @@
</cells> </cells>
</tableViewSection> </tableViewSection>
<tableViewSection headerTitle="Interaction" id="2hR-aI-CRP"> <tableViewSection headerTitle="Interaction" id="2hR-aI-CRP">
<cells> <cells/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" id="11q-UM-f40">
<rect key="frame" x="0.0" y="243.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="11q-UM-f40" id="Tp5-hX-pc3">
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Tabs" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BdH-U9-Vcz">
<rect key="frame" x="16" y="11.5" width="37" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="BdH-U9-Vcz" firstAttribute="centerY" secondItem="Tp5-hX-pc3" secondAttribute="centerY" id="OfE-gk-aMJ"/>
<constraint firstItem="BdH-U9-Vcz" firstAttribute="leading" secondItem="Tp5-hX-pc3" secondAttribute="leadingMargin" id="dVK-2S-b6A"/>
</constraints>
</tableViewCellContentView>
<connections>
<segue destination="JJN-aw-37c" kind="show" id="6oX-43-R1z"/>
</connections>
</tableViewCell>
</cells>
</tableViewSection> </tableViewSection>
</sections> </sections>
<connections> <connections>
@ -326,25 +308,6 @@
</objects> </objects>
<point key="canvasLocation" x="825" y="528"/> <point key="canvasLocation" x="825" y="528"/>
</scene> </scene>
<!--Tabs-->
<scene sceneID="D4Y-D0-S4g">
<objects>
<tableViewController id="JJN-aw-37c" customClass="TabsTableViewController" customModule="Tusker" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="M8r-EE-Z7d">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<connections>
<outlet property="dataSource" destination="JJN-aw-37c" id="dC9-LA-KZy"/>
<outlet property="delegate" destination="JJN-aw-37c" id="6Zp-me-GOX"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Tabs" id="GwP-CQ-WwZ"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8dk-2n-9cx" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1" y="1280"/>
</scene>
<!--Advanced--> <!--Advanced-->
<scene sceneID="xgj-Fx-53j"> <scene sceneID="xgj-Fx-53j">
<objects> <objects>

View File

@ -15,4 +15,8 @@ class PreferencesTableViewController: UITableViewController {
return navigationController return navigationController
} }
@IBAction func donePressed(_ sender: Any) {
dismiss(animated: true)
}
} }

View File

@ -1,92 +0,0 @@
//
// TabsTableViewController.swift
// Tusker
//
// Created by Shadowfacts on 10/5/18.
// Copyright © 2018 Shadowfacts. All rights reserved.
//
import UIKit
class TabsTableViewController: UITableViewController {
var tabs: [(Tab, Bool)] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "TabTableViewCell", bundle: nil), forCellReuseIdentifier: "tabCell")
tabs = Preferences.shared.tabs.filter { $0.value >= 0 }.sorted(by: { $0.value < $1.value }).map { ($0.key, true) }
tabs.append(contentsOf: Preferences.shared.tabs.filter { $0.value == -1 }.map { ($0.key, false) })
tableView.setEditing(true, animated: false)
}
func updatePreferences() {
var dict = [Tab: Int]()
var maxIndex = 0
for (tab, enabled) in tabs {
if enabled {
dict[tab] = maxIndex
maxIndex += 1
} else {
dict[tab] = -1
}
}
Preferences.shared.tabs = dict
guard let tabBarController = tabBarController as? MainTabBarViewController else { fatalError("Tab bar controller should be of type MainTabBarViewController") }
tabBarController.updateTabs(animated: true)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tabs.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "tabCell", for: indexPath) as? TabTableViewCell else { fatalError() }
let (tab, _) = tabs[indexPath.row]
cell.updateUI(for: tab)
cell.delegate = self
return cell
}
override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let tab = tabs.remove(at: sourceIndexPath.row)
tabs.insert(tab, at: destinationIndexPath.row)
updatePreferences()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
extension TabsTableViewController: TabTableViewCellDelegate {
func setEnabled(tab: Tab, enabled: Bool) {
let index = tabs.firstIndex(where: { $0.0 == tab })!
tabs[index] = (tab, enabled)
updatePreferences()
}
}

View File

@ -0,0 +1,47 @@
//
// MyProfileTableViewController.swift
// Tusker
//
// Created by Shadowfacts on 11/24/18.
// Copyright © 2018 Shadowfacts. All rights reserved.
//
import UIKit
class MyProfileTableViewController: ProfileTableViewController {
init(router: AppRouter) {
super.init(accountID: nil, router: router)
title = "My Profile"
MastodonController.getOwnAccount { (account) in
self.accountID = account.id
ImageCache.avatars.get(account.avatar, completion: { (data) in
guard let data = data else { return }
var image = UIImage(data: data)!
image = UIGraphicsImageRenderer(size: CGSize(width: 30, height: 30)).image(actions: { (_) in
image.draw(in: CGRect(x: 0, y: 0, width: 30, height: 30))
})
image = image.withRenderingMode(.alwaysOriginal)
self.tabBarItem.image = image
})
}
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Preferences", style: .plain, target: self, action: #selector(preferencesPressed))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
}
@objc func preferencesPressed() {
router.present(PreferencesTableViewController.create(), animated: true)
}
}

View File

@ -60,7 +60,6 @@ class TimelineTableViewController: EnhancedTableViewController {
self.refreshControl = UIRefreshControl() self.refreshControl = UIRefreshControl()
refreshControl!.addTarget(self, action: #selector(refreshStatuses(_:)), for: .valueChanged) refreshControl!.addTarget(self, action: #selector(refreshStatuses(_:)), for: .valueChanged)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(composePressed(_:)))
} }
required init?(coder aDecoder: NSCoder) { required init?(coder aDecoder: NSCoder) {