wip
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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
-1
@@ -1,4 +1,4 @@
|
||||
public class ExpoProTextUtil {
|
||||
public class ExpoSelectableTextUtil {
|
||||
public static func hexToUIColor(hex: String?) -> UIColor {
|
||||
guard let hex else {
|
||||
return UIColor.black
|
||||
+12
-4
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user