mirror of
https://github.com/metabolist/metatext.git
synced 2025-02-16 14:05:14 +00:00
Button improvements
This commit is contained in:
parent
68dc3ffa3f
commit
5f240b6ed8
5 changed files with 124 additions and 12 deletions
|
@ -110,6 +110,7 @@
|
||||||
D0F2D4DB257F018300986197 /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C6FAB252024BD003D0300 /* Array+Extensions.swift */; };
|
D0F2D4DB257F018300986197 /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01C6FAB252024BD003D0300 /* Array+Extensions.swift */; };
|
||||||
D0F2D54025818C4B00986197 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = D0F2D53F25818C4B00986197 /* Kingfisher */; };
|
D0F2D54025818C4B00986197 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = D0F2D53F25818C4B00986197 /* Kingfisher */; };
|
||||||
D0F2D5452581ABAB00986197 /* KingfisherOptionsInfo+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C7D46E24F76169001EBDBB /* KingfisherOptionsInfo+Extensions.swift */; };
|
D0F2D5452581ABAB00986197 /* KingfisherOptionsInfo+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C7D46E24F76169001EBDBB /* KingfisherOptionsInfo+Extensions.swift */; };
|
||||||
|
D0F2D54B2581CF7D00986197 /* VisualEffectBlur.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F2D54A2581CF7D00986197 /* VisualEffectBlur.swift */; };
|
||||||
D0FE1C8F253686F9003EF1EB /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE1C8E253686F9003EF1EB /* PlayerView.swift */; };
|
D0FE1C8F253686F9003EF1EB /* PlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE1C8E253686F9003EF1EB /* PlayerView.swift */; };
|
||||||
D0FE1C9825368A9D003EF1EB /* PlayerCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE1C9725368A9D003EF1EB /* PlayerCache.swift */; };
|
D0FE1C9825368A9D003EF1EB /* PlayerCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FE1C9725368A9D003EF1EB /* PlayerCache.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
@ -259,6 +260,7 @@
|
||||||
D0F0B12D251A97E400942152 /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
|
D0F0B12D251A97E400942152 /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
|
||||||
D0F0B135251AA12700942152 /* CollectionItem+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CollectionItem+Extensions.swift"; sourceTree = "<group>"; };
|
D0F0B135251AA12700942152 /* CollectionItem+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CollectionItem+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
D0F2D4D0257EE84400986197 /* NewStatusDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewStatusDataSource.swift; sourceTree = "<group>"; };
|
D0F2D4D0257EE84400986197 /* NewStatusDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewStatusDataSource.swift; sourceTree = "<group>"; };
|
||||||
|
D0F2D54A2581CF7D00986197 /* VisualEffectBlur.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualEffectBlur.swift; sourceTree = "<group>"; };
|
||||||
D0FE1C8E253686F9003EF1EB /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = "<group>"; };
|
D0FE1C8E253686F9003EF1EB /* PlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerView.swift; sourceTree = "<group>"; };
|
||||||
D0FE1C9725368A9D003EF1EB /* PlayerCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerCache.swift; sourceTree = "<group>"; };
|
D0FE1C9725368A9D003EF1EB /* PlayerCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerCache.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
@ -464,6 +466,7 @@
|
||||||
D0C7D42E24F76169001EBDBB /* TabNavigationView.swift */,
|
D0C7D42E24F76169001EBDBB /* TabNavigationView.swift */,
|
||||||
D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */,
|
D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */,
|
||||||
D0EA59472522B8B600804347 /* ViewConstants.swift */,
|
D0EA59472522B8B600804347 /* ViewConstants.swift */,
|
||||||
|
D0F2D54A2581CF7D00986197 /* VisualEffectBlur.swift */,
|
||||||
D0E1F582251F13EC00D45315 /* WebfingerIndicatorView.swift */,
|
D0E1F582251F13EC00D45315 /* WebfingerIndicatorView.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
|
@ -809,6 +812,7 @@
|
||||||
D0A1F4F7252E7D4B004435BF /* TableViewDataSource.swift in Sources */,
|
D0A1F4F7252E7D4B004435BF /* TableViewDataSource.swift in Sources */,
|
||||||
D0C7D4C424F7616A001EBDBB /* AppDelegate.swift in Sources */,
|
D0C7D4C424F7616A001EBDBB /* AppDelegate.swift in Sources */,
|
||||||
D0C7D49924F7616A001EBDBB /* AddIdentityView.swift in Sources */,
|
D0C7D49924F7616A001EBDBB /* AddIdentityView.swift in Sources */,
|
||||||
|
D0F2D54B2581CF7D00986197 /* VisualEffectBlur.swift in Sources */,
|
||||||
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */,
|
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */,
|
||||||
D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */,
|
D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */,
|
||||||
D0E1F583251F13EC00D45315 /* WebfingerIndicatorView.swift in Sources */,
|
D0E1F583251F13EC00D45315 /* WebfingerIndicatorView.swift in Sources */,
|
||||||
|
|
|
@ -40,6 +40,7 @@ class TableViewController: UITableViewController {
|
||||||
tableView.prefetchDataSource = self
|
tableView.prefetchDataSource = self
|
||||||
tableView.cellLayoutMarginsFollowReadableWidth = true
|
tableView.cellLayoutMarginsFollowReadableWidth = true
|
||||||
tableView.tableFooterView = UIView()
|
tableView.tableFooterView = UIView()
|
||||||
|
tableView.contentInset.bottom = Self.bottomInset
|
||||||
|
|
||||||
view.addSubview(webfingerIndicatorView)
|
view.addSubview(webfingerIndicatorView)
|
||||||
webfingerIndicatorView.translatesAutoresizingMaskIntoConstraints = false
|
webfingerIndicatorView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
@ -221,6 +222,8 @@ extension TableViewController: ZoomAnimatorDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension TableViewController {
|
private extension TableViewController {
|
||||||
|
static let bottomInset: CGFloat = .newStatusButtonDimension + .defaultSpacing * 4
|
||||||
|
|
||||||
var visibleLoadMoreViews: [LoadMoreView] {
|
var visibleLoadMoreViews: [LoadMoreView] {
|
||||||
tableView.visibleCells.compactMap { $0.contentView as? LoadMoreView }
|
tableView.visibleCells.compactMap { $0.contentView as? LoadMoreView }
|
||||||
}
|
}
|
||||||
|
@ -291,7 +294,7 @@ private extension TableViewController {
|
||||||
let indexPath = self.dataSource.indexPath(itemId: itemId) {
|
let indexPath = self.dataSource.indexPath(itemId: itemId) {
|
||||||
if self.viewModel.shouldAdjustContentInset {
|
if self.viewModel.shouldAdjustContentInset {
|
||||||
self.tableView.contentInset.bottom = max(
|
self.tableView.contentInset.bottom = max(
|
||||||
0,
|
Self.bottomInset,
|
||||||
self.tableView.frame.height
|
self.tableView.frame.height
|
||||||
- self.tableView.contentSize.height
|
- self.tableView.contentSize.height
|
||||||
- self.tableView.safeAreaInsets.top
|
- self.tableView.safeAreaInsets.top
|
||||||
|
|
|
@ -61,9 +61,6 @@ struct TabNavigationView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension TabNavigationView {
|
private extension TabNavigationView {
|
||||||
static let newStatusButtonDimension: CGFloat = 54
|
|
||||||
static let newStatusButtonShadowRadius: CGFloat = 2
|
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
var pendingView: some View {
|
var pendingView: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
|
@ -172,17 +169,16 @@ private extension TabNavigationView {
|
||||||
Button {
|
Button {
|
||||||
viewModel.presentingNewStatus = true
|
viewModel.presentingNewStatus = true
|
||||||
} label: {
|
} label: {
|
||||||
ZStack {
|
VisualEffectBlur(vibrancyStyle: .label) {
|
||||||
Circle()
|
|
||||||
Image(systemName: "pencil")
|
Image(systemName: "pencil")
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(
|
.frame(width: .newStatusButtonDimension / 2,
|
||||||
width: Self.newStatusButtonDimension / 2,
|
height: .newStatusButtonDimension / 2)
|
||||||
height: Self.newStatusButtonDimension / 2)
|
|
||||||
.accentColor(.white)
|
|
||||||
}
|
}
|
||||||
.frame(width: Self.newStatusButtonDimension, height: Self.newStatusButtonDimension)
|
.clipShape(Circle())
|
||||||
.shadow(radius: Self.newStatusButtonShadowRadius)
|
.frame(width: .newStatusButtonDimension,
|
||||||
|
height: .newStatusButtonDimension)
|
||||||
|
.shadow(radius: .newStatusButtonShadowRadius)
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ extension CGFloat {
|
||||||
static let hairline = 1 / UIScreen.main.scale
|
static let hairline = 1 / UIScreen.main.scale
|
||||||
static let minimumButtonDimension: Self = 44
|
static let minimumButtonDimension: Self = 44
|
||||||
static let barButtonItemDimension: Self = 28
|
static let barButtonItemDimension: Self = 28
|
||||||
|
static let newStatusButtonDimension: CGFloat = 54
|
||||||
|
static let newStatusButtonShadowRadius: CGFloat = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TimeInterval {
|
extension TimeInterval {
|
||||||
|
|
107
Views/VisualEffectBlur.swift
Normal file
107
Views/VisualEffectBlur.swift
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
// Copyright © 2020 Metabolist. All rights reserved.
|
||||||
|
|
||||||
|
// Taken from Apple's Fruta example code
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct VisualEffectBlur<Content: View>: View {
|
||||||
|
var blurStyle: UIBlurEffect.Style
|
||||||
|
var vibrancyStyle: UIVibrancyEffectStyle?
|
||||||
|
var content: Content
|
||||||
|
|
||||||
|
init(blurStyle: UIBlurEffect.Style = .systemMaterial,
|
||||||
|
vibrancyStyle: UIVibrancyEffectStyle? = nil,
|
||||||
|
@ViewBuilder content: () -> Content) {
|
||||||
|
self.blurStyle = blurStyle
|
||||||
|
self.vibrancyStyle = vibrancyStyle
|
||||||
|
self.content = content()
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Representable(
|
||||||
|
blurStyle: blurStyle,
|
||||||
|
vibrancyStyle: vibrancyStyle,
|
||||||
|
content: ZStack { content })
|
||||||
|
.accessibility(hidden: Content.self == EmptyView.self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension VisualEffectBlur {
|
||||||
|
struct Representable<Content: View>: UIViewRepresentable {
|
||||||
|
var blurStyle: UIBlurEffect.Style
|
||||||
|
var vibrancyStyle: UIVibrancyEffectStyle?
|
||||||
|
var content: Content
|
||||||
|
|
||||||
|
func makeUIView(context: Context) -> UIVisualEffectView {
|
||||||
|
context.coordinator.blurView
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIView(_ view: UIVisualEffectView, context: Context) {
|
||||||
|
context.coordinator.update(content: content, blurStyle: blurStyle, vibrancyStyle: vibrancyStyle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
Coordinator(content: content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension VisualEffectBlur.Representable {
|
||||||
|
class Coordinator {
|
||||||
|
let blurView = UIVisualEffectView()
|
||||||
|
let vibrancyView = UIVisualEffectView()
|
||||||
|
let hostingController: UIHostingController<Content>
|
||||||
|
|
||||||
|
init(content: Content) {
|
||||||
|
hostingController = UIHostingController(rootView: content)
|
||||||
|
hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
hostingController.view.backgroundColor = nil
|
||||||
|
blurView.contentView.addSubview(vibrancyView)
|
||||||
|
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
vibrancyView.contentView.addSubview(hostingController.view)
|
||||||
|
vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(content: Content, blurStyle: UIBlurEffect.Style, vibrancyStyle: UIVibrancyEffectStyle?) {
|
||||||
|
hostingController.rootView = content
|
||||||
|
|
||||||
|
let blurEffect = UIBlurEffect(style: blurStyle)
|
||||||
|
|
||||||
|
blurView.effect = blurEffect
|
||||||
|
|
||||||
|
if let vibrancyStyle = vibrancyStyle {
|
||||||
|
vibrancyView.effect = UIVibrancyEffect(blurEffect: blurEffect, style: vibrancyStyle)
|
||||||
|
} else {
|
||||||
|
vibrancyView.effect = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
hostingController.view.setNeedsDisplay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension VisualEffectBlur where Content == EmptyView {
|
||||||
|
init(blurStyle: UIBlurEffect.Style = .systemMaterial) {
|
||||||
|
self.init(blurStyle: blurStyle, vibrancyStyle: nil) {
|
||||||
|
EmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VisualEffectBlur_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
ZStack {
|
||||||
|
LinearGradient(
|
||||||
|
gradient: Gradient(colors: [.red, .blue]),
|
||||||
|
startPoint: .topLeading,
|
||||||
|
endPoint: .bottomTrailing
|
||||||
|
)
|
||||||
|
|
||||||
|
VisualEffectBlur(blurStyle: .systemUltraThinMaterial, vibrancyStyle: .fill) {
|
||||||
|
Text("Hello World!")
|
||||||
|
.frame(width: 200, height: 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue