Skip to content

Commit

Permalink
- Created the MoreViewController for the More Screen following the de…
Browse files Browse the repository at this point in the history
…sign guidelines described in #82

- Created new init methods in StaticTableViewRow and StaticTableViewSection to support NSAttributedString as titles.
- Created new UIPresentationController called CardPresentationController to support the presentation of a view controller in a "card" way.
- Coded support for NSAttributedString in ThemeTableViewCell.
  • Loading branch information
Pablo Carrascal committed Aug 22, 2018
1 parent 5de01b4 commit 907bd49
Show file tree
Hide file tree
Showing 9 changed files with 605 additions and 7 deletions.
29 changes: 28 additions & 1 deletion ownCloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
233BDEB5204FEFE500C06732 /* OwnCloudTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 233BDEB4204FEFE500C06732 /* OwnCloudTests.swift */; };
233E0FD82099F11D00C3D8D5 /* SecuritySettingsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 233E0FD72099F11D00C3D8D5 /* SecuritySettingsSection.swift */; };
2347446A20761BB700859C93 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2347446920761BB700859C93 /* String+Extension.swift */; };
236735A621217C3500E5834A /* MoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 236735A521217C3500E5834A /* MoreViewController.swift */; };
23957A6D209AFFE8003C8537 /* MoreSettingsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23957A6C209AFFE8003C8537 /* MoreSettingsSection.swift */; };
239F1319205A693A0029F186 /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239F1318205A693A0029F186 /* UIColor+Extension.swift */; };
239F437E20D0EE6300B1276D /* icon-search.tvg in Resources */ = {isa = PBXBuildFile; fileRef = 239F437D20D0EE6300B1276D /* icon-search.tvg */; };
23BEF1182076667F00DD2E6F /* IssuesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23BEF1172076667F00DD2E6F /* IssuesViewController.swift */; };
23C56537212167BE00BD4B47 /* CardPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C5652F212167BD00BD4B47 /* CardPresentationController.swift */; };
23C56538212167BE00BD4B47 /* CardTransitionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C56536212167BE00BD4B47 /* CardTransitionDelegate.swift */; };
23D0E09E205BCF8D002D7C80 /* ownCloudUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 230B84F020597F6E00C9F828 /* ownCloudUI.framework */; };
23D0E09F205BCF8D002D7C80 /* ownCloudUI.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 230B84F020597F6E00C9F828 /* ownCloudUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
23E22BB720C6A5C40024D11E /* UIDevice+UIUserInterfaceIdiom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23E22BB220C6A5C40024D11E /* UIDevice+UIUserInterfaceIdiom.swift */; };
Expand Down Expand Up @@ -291,10 +294,13 @@
233BDEBF204FEFF300C06732 /* ownCloudSDK.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ownCloudSDK.xcodeproj; path = "ios-sdk/ownCloudSDK.xcodeproj"; sourceTree = "<group>"; };
233E0FD72099F11D00C3D8D5 /* SecuritySettingsSection.swift */ = {isa = PBXFileReference; indentWidth = 8; lastKnownFileType = sourcecode.swift; path = SecuritySettingsSection.swift; sourceTree = "<group>"; tabWidth = 8; usesTabs = 1; };
2347446920761BB700859C93 /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
236735A521217C3500E5834A /* MoreViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoreViewController.swift; sourceTree = "<group>"; };
23957A6C209AFFE8003C8537 /* MoreSettingsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoreSettingsSection.swift; sourceTree = "<group>"; };
239F1318205A693A0029F186 /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
239F437D20D0EE6300B1276D /* icon-search.tvg */ = {isa = PBXFileReference; lastKnownFileType = text; path = "icon-search.tvg"; sourceTree = "<group>"; };
23BEF1172076667F00DD2E6F /* IssuesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssuesViewController.swift; sourceTree = "<group>"; };
23C5652F212167BD00BD4B47 /* CardPresentationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardPresentationController.swift; sourceTree = "<group>"; };
23C56536212167BE00BD4B47 /* CardTransitionDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CardTransitionDelegate.swift; sourceTree = "<group>"; };
23E22BB220C6A5C40024D11E /* UIDevice+UIUserInterfaceIdiom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIDevice+UIUserInterfaceIdiom.swift"; sourceTree = "<group>"; };
23F6238020B587EF004FDE8B /* SortMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortMethod.swift; sourceTree = "<group>"; };
23FA23E520BFD3D8009A6D73 /* SortBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SortBar.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -498,6 +504,23 @@
name = Products;
sourceTree = "<group>";
};
2366821521144DCD0045EF72 /* Card Presentation Controller */ = {
isa = PBXGroup;
children = (
23C5652F212167BD00BD4B47 /* CardPresentationController.swift */,
23C56536212167BE00BD4B47 /* CardTransitionDelegate.swift */,
);
path = "Card Presentation Controller";
sourceTree = "<group>";
};
236735A421217C2300E5834A /* Actions */ = {
isa = PBXGroup;
children = (
236735A521217C3500E5834A /* MoreViewController.swift */,
);
path = Actions;
sourceTree = "<group>";
};
2393696F207610F700BCE21A /* Recovered References */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -590,7 +613,7 @@
DC3BE0DB2077CC13002A0AC0 /* Client */ = {
isa = PBXGroup;
children = (
6E216A5C2112F55E00ED21BD /* Actions */,
236735A421217C2300E5834A /* Actions */,
DCFED971208095E200A2D984 /* ClientItemCell.swift */,
DC3BE0DC2077CC13002A0AC0 /* ClientQueryViewController.swift */,
DC3BE0DD2077CC13002A0AC0 /* ClientRootViewController.swift */,
Expand Down Expand Up @@ -778,6 +801,7 @@
DCF4F1622051927200189B9A /* UI Elements */ = {
isa = PBXGroup;
children = (
2366821521144DCD0045EF72 /* Card Presentation Controller */,
DCF4F17820519F8C00189B9A /* StaticTableViewController.swift */,
DCF4F17A20519F9D00189B9A /* StaticTableViewSection.swift */,
DCF4F17E2051A0D000189B9A /* StaticTableViewRow.swift */,
Expand Down Expand Up @@ -1174,6 +1198,7 @@
232F7CAF2097260400EE22E4 /* SettingsViewController.swift in Sources */,
DC85572C20513B8C00189B9A /* ServerListTableViewController.swift in Sources */,
233BDEA0204FEFE500C06732 /* AppDelegate.swift in Sources */,
236735A621217C3500E5834A /* MoreViewController.swift in Sources */,
23957A6D209AFFE8003C8537 /* MoreSettingsSection.swift in Sources */,
DCF4F1822051A94200189B9A /* GlobalSettingsViewController.swift in Sources */,
593BAB97209F8A0500023634 /* AppLockManager.swift in Sources */,
Expand All @@ -1189,9 +1214,11 @@
DC42244C207CAFBB0006A2A6 /* ThemeCollection.swift in Sources */,
DCFED9BA20809B8900A2D984 /* ThemeTVGResource.swift in Sources */,
DC3BE0DE2077CC14002A0AC0 /* ClientQueryViewController.swift in Sources */,
23C56538212167BE00BD4B47 /* CardTransitionDelegate.swift in Sources */,
DC1B270A209CF0D3004715E1 /* ConnectionIssueViewController.swift in Sources */,
DC0B37972051681600189B9A /* ThemeButton.swift in Sources */,
DCF4F17B20519F9D00189B9A /* StaticTableViewSection.swift in Sources */,
23C56537212167BE00BD4B47 /* CardPresentationController.swift in Sources */,
DC7DBA2B207F71E400E7337D /* VectorImageView.swift in Sources */,
DCE974BC207EACA60069FC2B /* UIImage+Extension.swift in Sources */,
DC1B2707209CF0D3004715E1 /* IssuesDismissalAnimator.swift in Sources */,
Expand Down
235 changes: 235 additions & 0 deletions ownCloud/Client/Actions/MoreViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
//
// MoreViewController.swift
// ownCloud
//
// Created by Pablo Carrascal on 25/07/2018.
// Copyright © 2018 ownCloud GmbH. All rights reserved.
//

/*
* Copyright (C) 2018, ownCloud GmbH.
*
* This code is covered by the GNU Public License Version 3.
*
* For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/
* You should have received a copy of this license along with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.en.html>.
*
*/

import UIKit
import ownCloudSDK

class MoreViewHeader: UIView {
private var iconView: UIImageView
private var titleLabel: UILabel
private var detailLabel: UILabel

var item: OCItem
weak var core: OCCore?

init(for item: OCItem, with core: OCCore) {
self.item = item
self.core = core

iconView = UIImageView()
titleLabel = UILabel()
detailLabel = UILabel()
super.init(frame: .zero)

render()
}

private func render() {
titleLabel.translatesAutoresizingMaskIntoConstraints = false
detailLabel.translatesAutoresizingMaskIntoConstraints = false
iconView.translatesAutoresizingMaskIntoConstraints = false
iconView.contentMode = .scaleAspectFit

titleLabel.font = UIFont.systemFont(ofSize: 17, weight: UIFont.Weight.semibold)
detailLabel.font = UIFont.systemFont(ofSize: 14)

detailLabel.textColor = UIColor.gray

self.addSubview(titleLabel)
self.addSubview(detailLabel)
self.addSubview(iconView)

iconView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 20).isActive = true
iconView.rightAnchor.constraint(equalTo: titleLabel.leftAnchor, constant: -15).isActive = true
iconView.rightAnchor.constraint(equalTo: detailLabel.leftAnchor, constant: -15).isActive = true

titleLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20).isActive = true
detailLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -20).isActive = true

iconView.widthAnchor.constraint(equalToConstant: 60).isActive = true
iconView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 20).isActive = true
titleLabel.bottomAnchor.constraint(equalTo: detailLabel.topAnchor, constant: -5).isActive = true
detailLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -20).isActive = true

iconView.setContentHuggingPriority(UILayoutPriority.required, for: UILayoutConstraintAxis.vertical)
titleLabel.setContentCompressionResistancePriority(UILayoutPriority.defaultHigh, for: UILayoutConstraintAxis.vertical)
detailLabel.setContentCompressionResistancePriority(UILayoutPriority.defaultHigh, for: UILayoutConstraintAxis.vertical)

titleLabel.attributedText = NSAttributedString(string: item.name, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 17, weight: .semibold)])
detailLabel.attributedText = NSAttributedString(string: item.name, attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 17, weight: .semibold)])

self.iconView.image = item.icon(fitInSize: CGSize(width: 40, height: 40))

if item.thumbnailAvailability != .none {
let displayThumbnail = { (thumbnail: OCItemThumbnail?) in
_ = thumbnail?.requestImage(for: CGSize(width: 60, height: 60), scale: 0, withCompletionHandler: { (thumbnail, error, _, image) in
if error == nil,
image != nil,
self.item.itemVersionIdentifier == thumbnail?.itemVersionIdentifier {
OnMainThread {
self.iconView.image = image
}
}
})
}

_ = core?.retrieveThumbnail(for: item, maximumSize: CGSize(width: 150, height: 150), scale: 0, retrieveHandler: { (error, _, _, thumbnail, _, progress) in
displayThumbnail(thumbnail)
})
}
titleLabel.numberOfLines = 0
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

class MoreViewController: UIViewController {

private var item: OCItem
private var core: OCCore

private var headerView: UIView
private var viewController: UIViewController

init(item: OCItem, core: OCCore, header: UIView, viewController: UIViewController) {
self.item = item
self.core = core
self.headerView = header
self.viewController = viewController

super.init(nibName: nil, bundle: nil)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

deinit {
Theme.shared.unregister(client: self)
}

override func viewDidLoad() {
super.viewDidLoad()

definesPresentationContext = true

Theme.shared.register(client: self)

headerView.translatesAutoresizingMaskIntoConstraints = false

view.addSubview(headerView)
NSLayoutConstraint.activate([
headerView.leftAnchor.constraint(equalTo: view.leftAnchor),
headerView.rightAnchor.constraint(equalTo: view.rightAnchor),
headerView.topAnchor.constraint(equalTo: view.topAnchor),
headerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 80)
])

view.addSubview(viewController.view)
viewController.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
viewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
viewController.view.leftAnchor.constraint(equalTo: view.leftAnchor),
viewController.view.rightAnchor.constraint(equalTo: view.rightAnchor),
viewController.view.topAnchor.constraint(equalTo: headerView.bottomAnchor),
viewController.view.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])

headerView.layer.shadowColor = UIColor.black.cgColor
headerView.layer.shadowOpacity = 0.1
headerView.layer.shadowRadius = 10
headerView.layer.cornerRadius = 10
headerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]

// Drag view
let dragView: UIView = UIView()
dragView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(dragView)
dragView.layer.cornerRadius = 2.5

NSLayoutConstraint.activate([
dragView.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
dragView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
dragView.widthAnchor.constraint(equalToConstant: 50),
dragView.heightAnchor.constraint(equalToConstant: 5)
])
dragView.backgroundColor = .lightGray
}
}

extension MoreViewController: Themeable {
func applyThemeCollection(theme: Theme, collection: ThemeCollection, event: ThemeEvent) {
self.headerView.backgroundColor = Theme.shared.activeCollection.tableBackgroundColor
}
}

class MoreStaticTableViewController: StaticTableViewController {

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let title = sections[section].headerAttributedTitle {
let containerView = UIView()
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(label)
NSLayoutConstraint.activate([
label.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 32),
label.topAnchor.constraint(equalTo: containerView.topAnchor),
label.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
label.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: -32)
])

label.attributedText = title
return containerView
}

return nil
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section != 0 {
return 56
}

return UITableViewAutomaticDimension
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if sections[section].headerAttributedTitle != nil || sections[section].headerTitle != nil {
return 56
}

return 0
}

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
if sections[section].footerAttributedTitle != nil || sections[section].footerTitle != nil {
return 56
}

return 0
}

override func applyThemeCollection(theme: Theme, collection: ThemeCollection, event: ThemeEvent) {
super.applyThemeCollection(theme: theme, collection: collection, event: event)
self.tableView.separatorColor = self.tableView.backgroundColor
}
}
Loading

0 comments on commit 907bd49

Please sign in to comment.