This commit is contained in:
Hailey
2024-01-11 02:01:20 -08:00
parent c6d2e54923
commit 648552eafb
15 changed files with 132 additions and 78 deletions
@@ -1,26 +0,0 @@
import ExpoModulesCore
public class ExpoProTextModule: Module {
public func definition() -> ModuleDefinition {
Name("ExpoProText")
View(ExpoProTextView.self) {
Events("onTextPress", "onTextLongPress")
Prop("segments") { (view: ExpoProTextView, prop: String) in
// Convert the JSON to segments
if let data = prop.data(using: .utf8) {
print("yes")
if let segments = try? JSONDecoder().decode(TextSegments.self, from: data) {
print("yes2")
view.segments = segments.segments
}
}
}
Prop("selectable") { (view: ExpoProTextView, prop: Bool) in
view.textView.isSelectable = prop
}
}
}
}
@@ -1,5 +1,5 @@
Pod::Spec.new do |s|
s.name = 'ExpoProText'
s.name = 'ExpoSelectableText'
s.version = '1.0.0'
s.summary = 'A sample project summary'
s.description = 'A sample project description'
@@ -16,6 +16,6 @@ Pod::Spec.new do |s|
'DEFINES_MODULE' => 'YES',
'SWIFT_COMPILATION_MODE' => 'wholemodule'
}
s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}"
end
@@ -0,0 +1,32 @@
import ExpoModulesCore
public class ExpoSelectableTextModule: Module {
public func definition() -> ModuleDefinition {
Name("ExpoSelectableText")
View(ExpoSelectableTextView.self) {
Events("onTextPress", "onTextLongPress", "onTextLayout")
Prop("segments") { (view: ExpoSelectableTextView, prop: String) in
// Convert the JSON to segments
if let data = prop.data(using: .utf8) {
if let segments = try? JSONDecoder().decode(TextSegments.self, from: data) {
view.segments = segments.segments
}
}
}
Prop("selectable") { (view: ExpoSelectableTextView, prop: Bool) in
view.textView.isSelectable = prop
}
Prop("rootStyle") { (view: ExpoSelectableTextView, prop: String) in
if let data = prop.data(using: .utf8) {
if let style = try? JSONDecoder().decode(TextStyle.self, from: data) {
view.style = style
}
}
}
}
}
}
@@ -1,4 +1,4 @@
public class ExpoProTextUtil {
public class ExpoSelectableTextUtil {
public static func hexToUIColor(hex: String?) -> UIColor {
guard let hex else {
return UIColor.black
@@ -1,13 +1,18 @@
import Foundation
import ExpoModulesCore
class ExpoProTextView: ExpoView {
class ExpoSelectableTextView: ExpoView {
let textView: UITextView = UITextView()
var segments: Array<TextSegment> = [] {
didSet {
setText()
}
}
var style: TextStyle? {
didSet {
self.setNeedsLayout()
}
}
let onTextPress = EventDispatcher()
let onTextLongPress = EventDispatcher()
@@ -22,6 +27,8 @@ class ExpoProTextView: ExpoView {
textView.isScrollEnabled = false
textView.backgroundColor = .clear
clipsToBounds = true
// Add the text view to the root view
addSubview(textView)
@@ -71,8 +78,8 @@ class ExpoProTextView: ExpoView {
segments.forEach { segment in
// Set some generic attributes that don't need ranges
let attributes: [NSAttributedString.Key:Any] = [
.font: UIFont.systemFont(ofSize: segment.style?.fontSize ?? 12.0, weight: segment.style?.fontWeight?.toFontWeight() ?? .regular),
.foregroundColor: ExpoProTextUtil.hexToUIColor(hex: segment.style?.color),
.font: UIFont.systemFont(ofSize: segment.style?.fontSize ?? self.style?.fontSize ?? 12.0, weight: segment.style?.fontWeight?.toFontWeight() ?? self.style?.fontWeight?.toFontWeight() ?? .regular),
.foregroundColor: ExpoSelectableTextUtil.hexToUIColor(hex: segment.style?.color),
]
// Create the attributed string with the generic attributes
@@ -81,7 +88,8 @@ class ExpoProTextView: ExpoView {
// Set the paragraph style attributes if necessary
if let lineHeight = segment.style?.lineHeight {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = lineHeight
paragraphStyle.minimumLineHeight = lineHeight
paragraphStyle.maximumLineHeight = lineHeight
string.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, string.length))
}
@@ -7,11 +7,21 @@ struct TextStyle: Decodable {
var textAlign: String? = "auto"
var lineHeight: Double?
var textDecorationLine: TextDecorationLine?
var flex: Int?
}
enum FontWeight: String, Decodable {
case bold
case normal
case one = "100"
case two = "200"
case three = "300"
case four = "400"
case five = "500"
case six = "600"
case seven = "700"
case eight = "800"
case nine = "900"
func toFontWeight() -> UIFont.Weight {
switch self {
@@ -19,6 +29,24 @@ enum FontWeight: String, Decodable {
return .bold
case .normal:
return .regular
case .one:
return .ultraLight
case .two:
return .ultraLight
case .three:
return .light
case .four:
return .regular
case .five:
return .medium
case .six:
return .semibold
case .seven:
return .semibold
case .eight:
return .bold
case .nine:
return .heavy
}
}
}
@@ -27,5 +55,6 @@ enum TextDecorationLine: String, Decodable {
case underline
case lineThrough = "line-through"
case underlineLineThrough = "underline line-through"
case normal
}