Skip to content

Commit

Permalink
Merge pull request #4 from NuPlay/test
Browse files Browse the repository at this point in the history
Add Collapse Button, Fix MoreButton Issue
  • Loading branch information
NuPlay authored Feb 6, 2022
2 parents 2cf79fe + 2dd3b92 commit 43d75cc
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 108 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ struct ExpandableText_Test: View {
.font(.body)//optional
.foregroundColor(.primary)//optional
.lineLimit(3)//optional
.animation(.easeOut)//optional
.expandButton(TextSet(text: "more", font: .body, color: .blue))
.collapseButton(TextSet(text: "less", font: .body, color: .blue))
.expandAnimation(.easeOut)//optional
.padding(.horizontal, 24)//optional
}
}
Expand All @@ -43,7 +45,8 @@ Modifier | Default
`.font(_ font: Font)` | `.body`
`.lineLimit(_ lineLimit: Int)` | `3`
`.foregroundColor(_ color: Color)` | `.primary`
`.expandButtonText(_ text: String)` | `"more"`
`.expandButtonColor(_ color: Color)` | `.blue`
`.expandButton(_ expandButton: TextSet)` | `TextSet(text: "more", font: .body, color: .blue)`
`.collapseButton(_ collapseButton: TextSet)` | `nil(If it's nil, it doesn't show)`
`.expandAnimation(_ animation: Animation?)` | `.none`


134 changes: 88 additions & 46 deletions Sources/ExpandableText/ExpandableText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ public struct ExpandableText: View {
var text : String

var font: Font = .body
var lineLimit : Int = 3
var foregroundColor : Color = .primary
var lineLimit: Int = 3
var foregroundColor: Color = .primary

var expandButtonText : String = "more"
var expandButtonColor : Color = .blue
var expandButton: TextSet = TextSet(text: "more", font: .body, color: .blue)
var collapseButton: TextSet? = nil

var animation: Animation? = .none

var uiFont: UIFont = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)
@State private var expand : Bool = false
@State private var truncated : Bool = false
@State private var size : CGFloat = 0

@State private var fullSize: CGFloat = 0

public init(text: String) {
self.text = text
Expand All @@ -32,6 +32,7 @@ public struct ExpandableText: View {
.font(font)
.foregroundColor(foregroundColor)
.lineLimit(expand == true ? nil : lineLimit)
.animation(animation, value: expand)
.mask(
VStack(spacing: 0){
Rectangle()
Expand All @@ -40,55 +41,96 @@ public struct ExpandableText: View {
HStack(spacing: 0){
Rectangle()
.foregroundColor(.black)
if !expand && truncated{
HStack(alignment: .bottom,spacing: 0){
LinearGradient(
gradient: Gradient(stops: [
Gradient.Stop(color: .black, location: 0),
Gradient.Stop(color: .clear, location: 0.8)]),
startPoint: .leading,
endPoint: .trailing)
.frame(width: 32, height: expandButtonText.heightOfString(usingFont: uiFont))

Rectangle()
.foregroundColor(.clear)
.frame(width: expandButtonText.widthOfString(usingFont: uiFont), alignment: .center)
if truncated{
if !expand {
HStack(alignment: .bottom,spacing: 0){
LinearGradient(
gradient: Gradient(stops: [
Gradient.Stop(color: .black, location: 0),
Gradient.Stop(color: .clear, location: 0.8)]),
startPoint: .leading,
endPoint: .trailing)
.frame(width: 32, height: expandButton.text.heightOfString(usingFont: fontToUIFont(font: expandButton.font)))

Rectangle()
.foregroundColor(.clear)
.frame(width: expandButton.text.widthOfString(usingFont: fontToUIFont(font: expandButton.font)), alignment: .center)
}
}
else if let collapseButton = collapseButton {
HStack(alignment: .bottom,spacing: 0){
LinearGradient(
gradient: Gradient(stops: [
Gradient.Stop(color: .black, location: 0),
Gradient.Stop(color: .clear, location: 0.8)]),
startPoint: .leading,
endPoint: .trailing)
.frame(width: 32, height: collapseButton.text.heightOfString(usingFont: fontToUIFont(font: collapseButton.font)))

Rectangle()
.foregroundColor(.clear)
.frame(width: collapseButton.text.widthOfString(usingFont: fontToUIFont(font: collapseButton.font)), alignment: .center)
}
}
}
}
.frame(height: expandButtonText.heightOfString(usingFont: uiFont))
.frame(height: expandButton.text.heightOfString(usingFont: fontToUIFont(font: font)))
}
)

if truncated && !expand {
Button(action: {
self.expand = true
}, label: {
Text(expandButtonText)
.font(font)
.foregroundColor(expandButtonColor)
})
if truncated {
if let collapseButton = collapseButton {
Button(action: {
self.expand.toggle()
}, label: {
Text(expand == false ? expandButton.text : collapseButton.text)
.font(expand == false ? expandButton.font : collapseButton.font)
.foregroundColor(expand == false ? expandButton.color : collapseButton.color)
})
}
else if !expand {
Button(action: {
self.expand = true
}, label: {
Text(expandButton.text)
.font(expandButton.font)
.foregroundColor(expandButton.color)
})
}
}
}
.background(
Text(text)
.lineLimit(lineLimit)
.background(GeometryReader { geo in
Color.clear.onAppear() {
let size = CGSize(width: geo.size.width, height: .greatestFiniteMagnitude)

let attributes:[NSAttributedString.Key:Any] = [NSAttributedString.Key.font: uiFont]
let attributedText = NSAttributedString(string: text, attributes: attributes)

let textSize = attributedText.boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, context: nil)

if textSize.size.height > geo.size.height {
truncated = true

self.size = textSize.size.height
}
ZStack{
if !truncated {
if fullSize != 0 {
Text(text)
.font(font)
.lineLimit(lineLimit)
.background(
GeometryReader { geo in
Color.clear
.onAppear {
if fullSize > geo.size.height {
self.truncated = true
print(geo.size.height)
}
}
}
)
}
})

Text(text)
.font(font)
.lineLimit(999)
.fixedSize(horizontal: false, vertical: true)
.background(GeometryReader { geo in
Color.clear
.onAppear() {
self.fullSize = geo.size.height
}
})
}
}
.hidden()
)
}
Expand Down
135 changes: 76 additions & 59 deletions Sources/ExpandableText/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,6 @@ extension ExpandableText {
public func font(_ font: Font) -> ExpandableText {
var result = self

if #available(iOS 14.0, *) {
switch font {
case .largeTitle:
result.uiFont = UIFont.preferredFont(forTextStyle: .largeTitle)
case .title:
result.uiFont = UIFont.preferredFont(forTextStyle: .title1)
case .title2:
result.uiFont = UIFont.preferredFont(forTextStyle: .title2)
case .title3:
result.uiFont = UIFont.preferredFont(forTextStyle: .title3)
case .headline:
result.uiFont = UIFont.preferredFont(forTextStyle: .headline)
case .subheadline:
result.uiFont = UIFont.preferredFont(forTextStyle: .subheadline)
case .callout:
result.uiFont = UIFont.preferredFont(forTextStyle: .callout)
case .caption:
result.uiFont = UIFont.preferredFont(forTextStyle: .caption1)
case .caption2:
result.uiFont = UIFont.preferredFont(forTextStyle: .caption2)
case .footnote:
result.uiFont = UIFont.preferredFont(forTextStyle: .footnote)
case .body:
result.uiFont = UIFont.preferredFont(forTextStyle: .body)
default:
result.uiFont = UIFont.preferredFont(forTextStyle: .body)
}
} else {
switch font {
case .largeTitle:
result.uiFont = UIFont.preferredFont(forTextStyle: .largeTitle)
case .title:
result.uiFont = UIFont.preferredFont(forTextStyle: .title1)
// case .title2:
// result.uiFont = UIFont.preferredFont(forTextStyle: .title2)
// case .title3:
// result.uiFont = UIFont.preferredFont(forTextStyle: .title3)
case .headline:
result.uiFont = UIFont.preferredFont(forTextStyle: .headline)
case .subheadline:
result.uiFont = UIFont.preferredFont(forTextStyle: .subheadline)
case .callout:
result.uiFont = UIFont.preferredFont(forTextStyle: .callout)
case .caption:
result.uiFont = UIFont.preferredFont(forTextStyle: .caption1)
// case .caption2:
// result.uiFont = UIFont.preferredFont(forTextStyle: .caption2)
case .footnote:
result.uiFont = UIFont.preferredFont(forTextStyle: .footnote)
case .body:
result.uiFont = UIFont.preferredFont(forTextStyle: .body)
default:
result.uiFont = UIFont.preferredFont(forTextStyle: .body)
}
}
result.font = font

return result
Expand All @@ -84,16 +29,24 @@ extension ExpandableText {
return result
}

public func expandButtonText(_ text: String) -> ExpandableText {
public func expandButton(_ expandButton: TextSet) -> ExpandableText {
var result = self

result.expandButtonText = text
result.expandButton = expandButton
return result
}
public func expandButtonColor(_ color: Color) -> ExpandableText {

public func collapseButton(_ collapseButton: TextSet) -> ExpandableText {
var result = self

result.collapseButton = collapseButton
return result
}

public func expandAnimation(_ animation: Animation?) -> ExpandableText {
var result = self

result.expandButtonColor = color
result.animation = animation
return result
}
}
Expand All @@ -111,3 +64,67 @@ extension String {
return size.width
}
}

public struct TextSet {
var text: String
var font: Font
var color: Color
}

func fontToUIFont(font: Font) -> UIFont {
if #available(iOS 14.0, *) {
switch font {
case .largeTitle:
return UIFont.preferredFont(forTextStyle: .largeTitle)
case .title:
return UIFont.preferredFont(forTextStyle: .title1)
case .title2:
return UIFont.preferredFont(forTextStyle: .title2)
case .title3:
return UIFont.preferredFont(forTextStyle: .title3)
case .headline:
return UIFont.preferredFont(forTextStyle: .headline)
case .subheadline:
return UIFont.preferredFont(forTextStyle: .subheadline)
case .callout:
return UIFont.preferredFont(forTextStyle: .callout)
case .caption:
return UIFont.preferredFont(forTextStyle: .caption1)
case .caption2:
return UIFont.preferredFont(forTextStyle: .caption2)
case .footnote:
return UIFont.preferredFont(forTextStyle: .footnote)
case .body:
return UIFont.preferredFont(forTextStyle: .body)
default:
return UIFont.preferredFont(forTextStyle: .body)
}
} else {
switch font {
case .largeTitle:
return UIFont.preferredFont(forTextStyle: .largeTitle)
case .title:
return UIFont.preferredFont(forTextStyle: .title1)
// case .title2:
// return UIFont.preferredFont(forTextStyle: .title2)
// case .title3:
// return UIFont.preferredFont(forTextStyle: .title3)
case .headline:
return UIFont.preferredFont(forTextStyle: .headline)
case .subheadline:
return UIFont.preferredFont(forTextStyle: .subheadline)
case .callout:
return UIFont.preferredFont(forTextStyle: .callout)
case .caption:
return UIFont.preferredFont(forTextStyle: .caption1)
// case .caption2:
// return UIFont.preferredFont(forTextStyle: .caption2)
case .footnote:
return UIFont.preferredFont(forTextStyle: .footnote)
case .body:
return UIFont.preferredFont(forTextStyle: .body)
default:
return UIFont.preferredFont(forTextStyle: .body)
}
}
}

0 comments on commit 43d75cc

Please sign in to comment.