π°π· νκ΅μ΄ Β Β |Β Β πΊπΈ English
InteractiveLabelμ ν
μ€νΈ λ΄μμ ν΄μνκ·Έ, λ©μ
, URL, μ΄λ©μΌ, μ¬μ©μ μ μ ν¨ν΄ λ±μ κ°μ§νμ¬ μνΈμμ©μ κ°λ₯νκ² νλ κ°λ ₯νκ³ μ μ°ν UILabel μλΈν΄λμ€μ
λλ€.
μ΄ νλ‘μ νΈλ λ μ΄μ μ μ§λ³΄μλμ§ μλ optonaut/ActiveLabel.swiftμ μ’μ κΈ°λ₯κ³Ό μμ΄λμ΄μ λͺ¨ν°λΈλ₯Ό μ»μ΄, νλμ μΈ Swift κΈ°λ₯(Combine, SwiftUI)κ³Ό λ λμ μν€ν μ²λ₯Ό μ μ©νμ¬ μλ‘κ² λ§λ€μ΄μ‘μ΅λλ€.
- λ€μν νμ κ°μ§: ν΄μνκ·Έ(#), λ©μ (@), URL, μ΄λ©μΌ κΈ°λ³Έ μ§μ
- μ¬μ©μ μ μ ν¨ν΄: μ κ·μμ μ¬μ©νμ¬ μνλ λͺ¨λ ν¨ν΄μ κ°μ§νκ³ μ²λ¦¬
- μ€μ κ°μ²΄ κΈ°λ°μ μμ¬μ΄ 컀μ€ν°λ§μ΄μ§:
InteractiveLabelConfigκ°μ²΄λ₯Ό ν΅ν΄ μμ, ν°νΈ, μ€ κ°κ²© λ± λͺ¨λ μκ°μ μμλ₯Ό ν κ³³μμ κ΄λ¦¬ - νλμ μΈ μ΄λ²€νΈ μ²λ¦¬: Combine
PassthroughSubject(didTap)λ₯Ό ν΅ν΄ ν μ΄λ²€νΈλ₯Ό λ°μνμΌλ‘ μ²λ¦¬ - νλΆν ν°μΉ κ²½ν: ν°μΉκ° μμλλ μ¦μ νμ΄λΌμ΄νΈκ° μ μ©λκ³ , ν°μΉ μμΉλ₯Ό λ²μ΄λλ©΄ ν΄μ λλ λ± μ¬μΈν μνΈμμ© μ 곡
- SwiftUI μ§μ:
InteractiveLabelViewλ₯Ό ν΅ν΄ SwiftUI νλ‘μ νΈμμ μμ½κ² μ¬μ© κ°λ₯ - κΉλν μν€ν
μ²:
TextManager,TouchManagerλ± μν λ³λ‘ μ± μμ΄ λͺ ννκ² λΆλ¦¬λμ΄ μ μ§λ³΄μ λ° νμ₯μ΄ μ©μ΄
- iOS: 13.0+
- Xcode: 14.0+
- Swift: 5.0+
Xcodeμμ File > Add Packages...λ₯Ό μ ννκ³ , μλμ μ μ₯μ URLμ μΆκ°ν©λλ€.
https://github.com/silexKhan/InteractiveLabel.git
import UIKit
import Combine
import InteractiveLabel
class ViewController: UIViewController {
private var cancellables = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
let label = InteractiveLabel()
label.numberOfLines = 0
label.text = "#ν΄μνκ·Έ, @λ©μ
, URL(https://github.com)μ λλ¬λ³΄μΈμ."
label.enabledTypes = [.hashtag, .mention, .url]
view.addSubview(label)
// ... μ€ν λ μ΄μμ μ€μ ...
// ν μ΄λ²€νΈ μ²λ¦¬
label.didTap
.sink { element in
self.handleTap(on: element)
}
.store(in: &cancellables)
}
func handleTap(on element: InteractiveElement) {
switch element {
case .hashtag(let hashtag):
print("Tapped hashtag: \(hashtag)")
case .mention(let mention):
print("Tapped mention: \(mention)")
case .url(let url, _):
print("Tapped URL: \(url)")
default:
break
}
}
}InteractiveLabelμ λͺ¨λ μκ°μ μμμ μ κ·μ ν¨ν΄μ config νλ‘νΌν°λ₯Ό ν΅ν΄ λ³κ²½ν μ μμ΅λλ€.
// InteractiveLabel μΈμ€ν΄μ€ μμ± ν
// μμ λ³κ²½
label.config.hashtagColor = .systemPurple
label.config.hashtagSelectedColor = .systemIndigo
label.config.mentionColor = .systemOrange
// νμ΄λΌμ΄νΈ μ ν°νΈ λ³κ²½
label.config.highlightFontName = "Helvetica-Bold"
label.config.highlightFontSize = label.font.pointSize
// URL μ΅λ κΈΈμ΄ μ€μ
label.config.urlMaximumLength = 30
// μ¬μ©μ μ μ ν¨ν΄ μΆκ°
let customType = InteractiveType.custom(pattern: "silex")
label.enabledTypes.append(customType)
label.config.customColor[customType] = .systemGreen
label.handleCustom(for: customType) { customString in
print("Custom type tapped: \(customString)")
}μ΄μ μ 보 λ° κΈ°λ₯ μ μ, Pull Request λ± λͺ¨λ μ’ λ₯μ κΈ°μ¬λ₯Ό νμν©λλ€.
- ActiveLabel.swift (μ΄ νλ‘μ νΈμ λͺ¨ν°λΈ)
- TTTAttributedLabel
- KILabel
- silex
- Email: realsilex@gmail.com
InteractiveLabelμ MIT λΌμ΄μ μ€μ λ°λΌ λ°°ν¬λ©λλ€. μμΈν λ΄μ©μ LICENSE νμΌμ μ°Έκ³ νμμμ€.
InteractiveLabel is a powerful and flexible UILabel subclass that detects patterns like hashtags, mentions, URLs, emails, and custom patterns within text, enabling interaction.
This project was inspired by the great features and ideas of the no-longer-maintained optonaut/ActiveLabel.swift, and has been newly created with modern Swift features (Combine, SwiftUI) and a better architecture.
- Multiple Type Detection: Default support for hashtags (#), mentions (@), URLs, and emails.
- Custom Patterns: Detect and handle any custom pattern using regular expressions.
- Easy Customization via Config Object: Manage all visual elements like colors, fonts, and line spacing in one place with the
InteractiveLabelConfigobject. - Modern Event Handling: Handle tap events reactively through a Combine
PassthroughSubject(didTap). - Rich Touch Experience: Provides delicate interactions, such as highlighting immediately on touch-down and releasing when the touch moves away.
- SwiftUI Support: Easily usable in SwiftUI projects with
InteractiveLabelView. - Clean Architecture: Responsibilities are clearly separated by roles (
TextManager,TouchManager), making it easy to maintain and extend.
- iOS: 13.0+
- Xcode: 14.0+
- Swift: 5.0+
In Xcode, select File > Add Packages... and add the repository URL below.
https://github.com/silexKhan/InteractiveLabel.git
import UIKit
import Combine
import InteractiveLabel
class ViewController: UIViewController {
private var cancellables = Set<AnyCancellable>()
override func viewDidLoad() {
super.viewDidLoad()
let label = InteractiveLabel()
label.numberOfLines = 0
label.text = "Tap on a #hashtag, @mention, or URL like https://github.com."
label.enabledTypes = [.hashtag, .mention, .url]
view.addSubview(label)
// ... set up auto layout ...
// Handle tap events
label.didTap
.sink { element in
self.handleTap(on: element)
}
.store(in: &cancellables)
}
func handleTap(on element: InteractiveElement) {
switch element {
case .hashtag(let hashtag):
print("Tapped hashtag: \(hashtag)")
case .mention(let mention):
print("Tapped mention: \(mention)")
case .url(let url, _):
print("Tapped URL: \(url)")
default:
break
}
}
}All visual elements and regex patterns of InteractiveLabel can be changed via the config property.
// After creating an InteractiveLabel instance
// Change colors
label.config.hashtagColor = .systemPurple
label.config.hashtagSelectedColor = .systemIndigo
label.config.mentionColor = .systemOrange
// Change font on highlight
label.config.highlightFontName = "Helvetica-Bold"
label.config.highlightFontSize = label.font.pointSize
// Set max URL length
label.config.urlMaximumLength = 30
// Add a custom pattern
let customType = InteractiveType.custom(pattern: "silex")
label.enabledTypes.append(customType)
label.config.customColor[customType] = .systemGreen
label.handleCustom(for: customType) { customString in
print("Custom type tapped: \(customString)")
}All kinds of contributions are welcome, including issue reports, feature suggestions, and Pull Requests.
- ActiveLabel.swift (The motive for this project)
- TTTAttributedLabel
- KILabel
- silex
- Email: realsilex@gmail.com
InteractiveLabel is distributed under the MIT license. See LICENSE for more information.