Skip to content

Commit

Permalink
Improve text input view (#2833)
Browse files Browse the repository at this point in the history

Co-authored-by: Ryan Lepinski <[email protected]>
  • Loading branch information
khmMouna and rlepinski authored Oct 11, 2023
1 parent 628b500 commit 9a93cd0
Show file tree
Hide file tree
Showing 8 changed files with 2,212 additions and 117 deletions.
5 changes: 2 additions & 3 deletions Airship/AirshipCore/Source/BannerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ struct BannerView: View {
}
}

#if !os(watchOS)

#if !os(watchOS)
private func createBanner(
placement: BannerPlacement,
metrics: GeometryProxy
Expand Down Expand Up @@ -128,7 +127,7 @@ struct BannerView: View {
.constraints(contentConstraints, alignment: alignment, fixedSize: true)
.applyIf(ignoreSafeArea) { $0.edgesIgnoringSafeArea(.all)}
}
#endif
#endif

private func resolvePlacement(
orientation: Orientation,
Expand Down
133 changes: 116 additions & 17 deletions Airship/AirshipCore/Source/FontViewModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,22 @@
import Foundation
import SwiftUI


struct TextAppearanceViewModifier<Appearance: BaseTextAppearance>: ViewModifier
{
let textAppearance: Appearance

// Needed for dynamic font size
@Environment(\.sizeCategory) var sizeCategory

@ViewBuilder
func body(content: Content) -> some View {
content.font(resolveFont())
content.font(UIFont.resolveFont(self.textAppearance))
}

private func resolveFont() -> Font {
var font: Font
let scaledSize = UIFontMetrics.default.scaledValue(for: self.textAppearance.fontSize)

if let fontFamily = resolveFontFamily(
families: self.textAppearance.fontFamilies
) {
Expand All @@ -30,7 +29,7 @@ struct TextAppearanceViewModifier<Appearance: BaseTextAppearance>: ViewModifier
} else {
font = Font.system(size: scaledSize)
}

if let styles = self.textAppearance.styles {
if styles.contains(.bold) {
font = font.bold()
Expand All @@ -41,12 +40,12 @@ struct TextAppearanceViewModifier<Appearance: BaseTextAppearance>: ViewModifier
}
return font
}

private func resolveFontFamily(families: [String]?) -> String? {
if let families = families {
for family in families {
let lowerCased = family.lowercased()

switch lowerCased {
case "serif":
return "Times New Roman"
Expand All @@ -61,30 +60,28 @@ struct TextAppearanceViewModifier<Appearance: BaseTextAppearance>: ViewModifier
}
return nil
}

}


extension Text {

private func applyTextStyles(styles: [TextStyle]?) -> Text {
var text = self
if let styles = styles {
if styles.contains(.bold) {
text = text.bold()
}

if styles.contains(.italic) {
text = text.italic()
}

if styles.contains(.underlined) {
text = text.underline()
}
}
return text
}

@ViewBuilder
func textAppearance<Appearance: BaseTextAppearance>(
_ textAppearance: Appearance?
Expand All @@ -104,20 +101,122 @@ extension Text {
}
}

extension View {

@ViewBuilder
func applyViewAppearance<Appearance: BaseTextAppearance>(
_ textAppearance: Appearance?
) -> some View {
if let textAppearance = textAppearance {
self
.multilineTextAlignment(
textAppearance.alignment?.toSwiftTextAlignment() ?? .center
)
.modifier(
TextAppearanceViewModifier(textAppearance: textAppearance)
)
.foreground(textAppearance.color)
} else {
self
}
}
}

extension UIFont {

func withTraits(traits: UIFontDescriptor.SymbolicTraits) -> UIFont {
if let descriptor = fontDescriptor.withSymbolicTraits(traits) {
return UIFont(descriptor: descriptor, size: 0) //size 0 means keep the size as it is
} else {
return self
}
}

func bold() -> UIFont {
return withTraits(traits: .traitBold)
}

func italic() -> UIFont {
return withTraits(traits: .traitItalic)
}

static func resolveUIFont<Appearance: BaseTextAppearance>(
_ textAppearance: Appearance
) -> UIFont {
var font = UIFont()
let scaledSize = UIFontMetrics.default.scaledValue(for: textAppearance.fontSize)

if let fontFamily = resolveFontFamily(
families: textAppearance.fontFamilies
) {
font =
UIFont(
name: fontFamily,
size: scaledSize
)
?? UIFont()
} else {
font = UIFont.systemFont(
ofSize: scaledSize
)
}

if let styles = textAppearance.styles {
if styles.contains(.bold) {
font = font.bold()
}
if styles.contains(.italic) {
font = font.italic()
}
}
return font
}

static func resolveFont<Appearance: BaseTextAppearance>(
_ textAppearance: Appearance
) -> Font {
var font: Font
let scaledSize = UIFontMetrics.default.scaledValue(for: textAppearance.fontSize)

if let fontFamily = resolveFontFamily(
families: textAppearance.fontFamilies
) {
font = Font.custom(
fontFamily,
size: scaledSize
)
} else {
font = Font.system(size: scaledSize)
}

if let styles = textAppearance.styles {
if styles.contains(.bold) {
font = font.bold()
}
if styles.contains(.italic) {
font = font.italic()
}
}
return font
}

static func resolveFontFamily(families: [String]?) -> String? {
if let families = families {
for family in families {
let lowerCased = family.lowercased()

switch lowerCased {
case "serif":
return "Times New Roman"
case "sans-serif":
return nil
default:
if !UIFont.fontNames(forFamilyName: lowerCased).isEmpty {
return family
}
}
}
}
return nil
}
}
21 changes: 18 additions & 3 deletions Airship/AirshipCore/Source/ScrollLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,30 @@ struct ScrollLayout: View {
self.constraints = constraints
}

@ViewBuilder
private func makeScrollView(axis: Axis.Set) -> some View {

if #available(iOS 16.0, *) {
ScrollView(axis) {
makeContent()
}
.scrollDismissesKeyboard(
self.thomasEnvironment.focusedID != nil ? .immediately : .never
)
} else {
ScrollView(axis) {
makeContent()
}
}
}

@ViewBuilder
private func makeScrollView() -> some View {
let isVertical = self.model.direction == .vertical
let axis = isVertical ? Axis.Set.vertical : Axis.Set.horizontal

ScrollViewReader { proxy in
ScrollView(axis) {
makeContent()
}
makeScrollView(axis: axis)
.clipped()
.onChange(
of: self.thomasEnvironment.keyboardState
Expand Down
Loading

0 comments on commit 9a93cd0

Please sign in to comment.