forked from shadowfacts/Tusker
Redo app navigation/tab bar
This commit is contained in:
parent
656cc1d3ef
commit
fe85e3c1d6
|
@ -57,7 +57,7 @@
|
|||
D6109A0D214599E100432DC2 /* RequestRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0C214599E100432DC2 /* RequestRange.swift */; };
|
||||
D6109A0F21459B6900432DC2 /* Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6109A0E21459B6900432DC2 /* Pagination.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 */; };
|
||||
D621544D21682AD90003D87D /* TabTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D621544C21682AD90003D87D /* TabTableViewCell.xib */; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -569,6 +569,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
D667E5E621349D4C0057A976 /* ProfileTableViewController.swift */,
|
||||
D6163F2B21AA0AF1008DAC41 /* MyProfileTableViewController.swift */,
|
||||
);
|
||||
path = Profile;
|
||||
sourceTree = "<group>";
|
||||
|
@ -615,7 +616,6 @@
|
|||
D663626521360DD700C9CBA2 /* Preferences.storyboard */,
|
||||
D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */,
|
||||
D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */,
|
||||
D621544721682A9D0003D87D /* TabsTableViewController.swift */,
|
||||
D627FF80217FE8F400CC0648 /* BehaviorTableViewController.swift */,
|
||||
D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */,
|
||||
);
|
||||
|
@ -1183,7 +1183,6 @@
|
|||
D6434EB3215B1856001A919A /* XCBRequest.swift in Sources */,
|
||||
D663626221360B1900C9CBA2 /* Preferences.swift in Sources */,
|
||||
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */,
|
||||
D621544821682A9D0003D87D /* TabsTableViewController.swift in Sources */,
|
||||
D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */,
|
||||
04496BD721625361001F1B23 /* ContentLabel.swift in Sources */,
|
||||
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */,
|
||||
|
@ -1215,6 +1214,7 @@
|
|||
D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */,
|
||||
D667E5E721349D4C0057A976 /* ProfileTableViewController.swift in Sources */,
|
||||
D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */,
|
||||
D6163F2C21AA0AF1008DAC41 /* MyProfileTableViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -66,6 +66,8 @@ class ComposeViewController: UIViewController {
|
|||
|
||||
super.init(nibName: "ComposeViewController", bundle: nil)
|
||||
|
||||
title = "Compose"
|
||||
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelPressed))
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Drafts", style: .plain, target: self, action: #selector(draftsPressed))
|
||||
}
|
||||
|
|
|
@ -8,48 +8,22 @@
|
|||
|
||||
import UIKit
|
||||
|
||||
class MainTabBarViewController: UITabBarController {
|
||||
class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate {
|
||||
|
||||
lazy var router = AppRouter(root: self)
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
updateTabs(animated: false)
|
||||
}
|
||||
|
||||
func updateTabs(animated: Bool) {
|
||||
let currentTabs = Preferences.shared.tabs.filter { $1 >= 0 }.sorted { $1.1 > $0.1 }.map { $0.key }
|
||||
let viewControllers: [UIViewController] = currentTabs.map { (tab) in
|
||||
if tab == .preferences, let preferences = selectedViewController {
|
||||
return preferences
|
||||
} else {
|
||||
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()
|
||||
}
|
||||
self.delegate = self
|
||||
|
||||
viewControllers = [
|
||||
embedInNavigationController(TimelineTableViewController(for: .home, router: router)),
|
||||
embedInNavigationController(NotificationsTableViewController(router: router)),
|
||||
ComposeViewController(router: router),
|
||||
embedInNavigationController(TimelineTableViewController(for: .public(local: false), router: router)),
|
||||
embedInNavigationController(MyProfileTableViewController(router: router)),
|
||||
]
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?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">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<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"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
@ -93,7 +93,13 @@
|
|||
<outlet property="delegate" destination="ArB-e7-yko" id="BFj-a8-oE6"/>
|
||||
</connections>
|
||||
</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>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="GBL-Cz-yNZ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
|
@ -198,31 +204,7 @@
|
|||
</cells>
|
||||
</tableViewSection>
|
||||
<tableViewSection headerTitle="Interaction" id="2hR-aI-CRP">
|
||||
<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>
|
||||
<cells/>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
|
@ -326,25 +308,6 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="825" y="528"/>
|
||||
</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-->
|
||||
<scene sceneID="xgj-Fx-53j">
|
||||
<objects>
|
||||
|
|
|
@ -15,4 +15,8 @@ class PreferencesTableViewController: UITableViewController {
|
|||
return navigationController
|
||||
}
|
||||
|
||||
@IBAction func donePressed(_ sender: Any) {
|
||||
dismiss(animated: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -60,7 +60,6 @@ class TimelineTableViewController: EnhancedTableViewController {
|
|||
|
||||
self.refreshControl = UIRefreshControl()
|
||||
refreshControl!.addTarget(self, action: #selector(refreshStatuses(_:)), for: .valueChanged)
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(composePressed(_:)))
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
|
Loading…
Reference in New Issue