当前位置:网站首页>Several methods of opening URL in swiftui view
Several methods of opening URL in swiftui view
2022-07-28 14:39:00 【Dongpo Pig Knuckle】
Visit my blog www.fatbobman.com[1] You can get a better reading experience
This article will introduce you to SwiftUI Open in view URL Several ways of , Other content includes how to automatically recognize the content in the text and convert it into clickable links , And how to customize the opening URL Before and after behavior, etc .
The example code of this article is in Swift Playgrounds 4.1 ( macOS edition ) Done in , Can be found in Download here [2]. Learn more about Swift Playgrounds The content of , You can refer to Swift Playgrounds 4 Entertainment or productivity [3] One article .
image-20220520182722773
SwiftUI 1.0( iOS 13、Catalina )
In the view , Developers usually need to deal with two different types of opening URL The situation of :
- Click a button ( Or similar components ) Open the specified URL
- Turn part of the text into a clickable area , Click to open the specified URL
Unfortunately ,1.0 In the era of SwiftUI Quite young , There is no native way to deal with the above two scenarios .
For the first scenario , The common practice is :
// iOS
Button("Wikipedia"){
UIApplication.shared.open(URL(string:"https://www.wikipedia.org")!)
}
// macOS
Button("Wikipedia"){
NSWorkspace.shared.open(URL(string:"https://www.wikipedia.org")!)
}
The second scenario is quite troublesome to implement , Need packing UITextView( or UILabel ) And cooperate with NSAttributedString Let's do it together , here SwiftUI It is only used as a layout tool .
SwiftUI 2.0( iOS 14、Big sur )
SwiftUI 2.0 Provides a fairly perfect native solution for the first scenario , But we still can't deal with the second scenario in a native way .
openURL
openURL yes SwiftUI 2.0 An environment value added in ( EnvironmentValue ), It has two functions :
- By calling its callFunction Method , Open up URL The action of
At this time in Button in , We can go straight through openURL To complete in SwiftUI 1.0 In the version, by calling other frameworks API The work that can be done .
struct Demo: View {
@Environment(\.openURL) private var openURL // Introduce environmental values
var body: some View {
Button {
if let url = URL(string: "https://www.example.com") {
openURL(url) { accepted in // By setting completion Closure , You can check whether it has been completed URL On . State by OpenURLAction Provide
print(accepted ? "Success" : "Failure")
}
}
} label: {
Label("Get Help", systemImage: "person.fill.questionmark")
}
}
}
- By providing OpenURLAction , Custom through openURL The act of opening a link ( It will be explained in detail later )
Link
SwiftUI 2.0 Provides a combination of Button and openURL Of Link Control , Help developers further simplify code :
Link(destination: URL(string: "mailto://[email protected]")!, label: {
Image(systemName: "envelope.fill")
Text(" email ")
})
SwiftUI 3.0( iOS 15、Monterey )
3.0 Time , With Text Function enhancement and AttributedString Appearance ,SwiftUI Finally made up another short board —— Turn part of the text into a clickable area , Click to open the specified URL.
Text Use cases 1 : Automatic identification LocalizedStringKey Medium URL
By supporting LocalizedStringKey Created by the construction method of Text , It will automatically recognize the... In the text website ( Developers don't have to make any settings ), Click to open the corresponding URL .
Text("www.wikipedia.org 13900000000 [email protected]") // The default parameter type is LocalizedStringKey Constructor
image-20220520141225595
This method can only identify the network address ( Web address 、 Email address, etc ), Therefore, the telephone number in the code cannot be automatically recognized .
Please note that , The following code uses the parameter type String Constructor , therefore Text Will not automatically recognize... In content URL :
let text = "www.wikipedia.org 13900000000 [email protected]" // The type is String
Text(text) // Parameter type is String The constructor of does not support automatic recognition
Text Use cases 2 : distinguish Markdown The grammatical URL Mark
SwiftUI 3.0 Of Text , When the content type is LocalizedStringKey when ,Text It's possible to do some of the Markdown Parsing syntax tags :
Text("[Wikipedia](https://www.wikipedia.org "Wikipedia") ~~Hi~~ [13900000000](tel://13900000000 "13900000000")")
In this way , We can use any kind of URI ( Not limited to the network ), For example, make a call in the code .
image-20220522085352243
Text Use cases 3 : contain link The information of AttributedString
stay WWDC 2021 On , Apple launched NSAttributedString Value type version of AttributedString, And can be used directly in Text in . By means of AttributedString Set different properties for text in different positions in , So as to realize Text Open in URL The function of .
let attributedString:AttributedString = {
var fatbobman = AttributedString(" Elbow Swift Notepad ")
fatbobman.link = URL(string: "https://www.fatbobman.com")!
fatbobman.font = .title
fatbobman.foregroundColor = .green // link Not for nil Of Run, Custom foreground colors and underscores are automatically masked
var tel = AttributedString(" Phone number ")
tel.link = URL(string:"tel://13900000000")
tel.backgroundColor = .yellow
var and = AttributedString(" and ")
and.foregroundColor = .red
return fatbobman + and + tel
}()
Text(attributedString)
image-20220520144103395
More information about AttributedString The content of , see also AttributedString—— Not only make the words more beautiful [4]
Text Use cases 4 : Identify... In a string URL Information , Translates into AttributedString
Above 3 In two use cases , except Use cases 1 It can automatically identify the network address in the text , The other two use cases need to be explicitly added by the developer in some way URL Information .
Developers can use NSDataDetector + AttributedString The combination of , So as to realize similar system information 、 mail 、 WeChat app like that , Automatic recognition of different types of content in text , And set the corresponding URL.
NSDataDetector[5] yes NSRegularExpression Subclasses of , It can detect semi-structured information in natural language text , Such as date 、 Address 、 link 、 Phone number 、 Traffic information, etc , It is widely used in various system applications provided by Apple .
let text = "https://www.wikipedia.org 13900000000 [email protected]"
// Set the type to be recognized
let types = NSTextCheckingResult.CheckingType.link.rawValue | NSTextCheckingResult.CheckingType.phoneNumber.rawValue
// Create recognizer
let detector = try! NSDataDetector(types: types)
// Get recognition results
let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.count))
// Process the inspection results one by one
for match in matches {
if match.resultType == .date {
...
}
}
You can take NSDataDetector Think of it as a regular expression encapsulation suite with extremely high complexity .
The complete code is as follows :
extension String {
func toDetectedAttributedString() -> AttributedString {
var attributedString = AttributedString(self)
let types = NSTextCheckingResult.CheckingType.link.rawValue | NSTextCheckingResult.CheckingType.phoneNumber.rawValue
guard let detector = try? NSDataDetector(types: types) else {
return attributedString
}
let matches = detector.matches(in: self, options: [], range: NSRange(location: 0, length: count))
for match in matches {
let range = match.range
let startIndex = attributedString.index(attributedString.startIndex, offsetByCharacters: range.lowerBound)
let endIndex = attributedString.index(startIndex, offsetByCharacters: range.length)
// by link Set up url
if match.resultType == .link, let url = match.url {
attributedString[startIndex..<endIndex].link = url
// If it's email , Set background color
if url.scheme == "mailto" {
attributedString[startIndex..<endIndex].backgroundColor = .red.opacity(0.3)
}
}
// by Phone number Set up url
if match.resultType == .phoneNumber, let phoneNumber = match.phoneNumber {
let url = URL(string: "tel:\(phoneNumber)")
attributedString[startIndex..<endIndex].link = url
}
}
return attributedString
}
}
Text("https://www.wikipedia.org 13900000000 [email protected]".toDetectedAttributedString())
image-20220520150754052
Customize Text The color of the link in
Unfortunately , Even if we've been for AttributedString Set the foreground color , But when a paragraph of text link Properties of nil when ,Text Its foreground color and underline settings are automatically ignored , Use the system default link Render settings to display .
At present, you can change... By setting shading Text All of them link Color :
Text("www.wikipedia.org 13900000000 [email protected]")
.tint(.green)
Link("Wikipedia", destination: URL(string: "https://www.wikipedia.org")!)
.tint(.pink)
image-20220520151737202
Comparison Text Fixed style of links in , It can be used Button or Link Create a link button that can customize the appearance freely :
Button(action: {
openURL(URL(string: "https://www.wikipedia.org")!)
}, label: {
Circle().fill(.angularGradient(.init(colors: [.red,.orange,.pink]), center: .center, startAngle: .degrees(0), endAngle: .degrees(360)))
})
image-20220520164125700
Customize openURL act
stay Button in , We can add logic code to the closure , Custom open URL Before and after .
Button(" Open the web page ") {
if let url = URL(string: "https://www.example.com") {
// Turn on URL Previous behavior
print(url)
openURL(url) { accepted in // By setting completion Closure , Define click URL Post action
print(accepted ? "Open success" : "Open failure")
}
}
}
But in Link and Text in , We need to set the environment value openURL Provide OpenURLAction Handle the code to customize the behavior of opening links .
Text("Visit [Example Company](https://www.example.com "Example Company") for details.")
.environment(\.openURL, OpenURLAction { url in
handleURL(url)
return .handled
})
OpenURLAction The structure is as follows :
public struct OpenURLAction {
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
public init(handler: @escaping (URL) -> OpenURLAction.Result)
public struct Result {
public static let handled: OpenURLAction.Result // The current code has processed the URL , The invocation behavior is no longer passed down
public static let discarded: OpenURLAction.Result // The current processing code will discard the URL , The invocation behavior is no longer passed down
public static let systemAction: OpenURLAction.Result // The current code does not handle , The calling behavior is passed down ( If the outer layer is not customized by the user OpenURLAction , The default implementation of the system is used )
public static func systemAction(_ url: URL) -> OpenURLAction.Result // The current code does not handle , New URL Pass down ( If the outer layer is not customized by the user OpenURLAction , The default implementation of the system is used )
}
}
such as :
Text("www.fatbobman.com [email protected] 13900000000".toDetectedAttributedString()) // Create three links https mailto tel
.environment(\.openURL, OpenURLAction { url in
switch url.scheme {
case "mailto":
return .discarded // The mail will be discarded directly , Don't deal with
default:
return .systemAction // Other types URI To the next level ( Outer layer )
}
})
.environment(\.openURL, OpenURLAction { url in
switch url.scheme {
case "tel":
print("call number \(url.absoluteString)") // Print phone number
return .handled // Inform that it has been handled , Will not continue to the next level
default:
return .systemAction // Other types URI The current code does not handle , Directly to the next layer
}
})
.environment(\.openURL, OpenURLAction { _ in
.systemAction(URL(string: "https://www.apple.com")!) // Since we did not continue to set after this layer OpenURLAction , Therefore, it will eventually call the implementation of the system to open the apple official website
})
This processing method of setting the environment value layer by layer , It gives developers a lot of freedom . stay SwiftUI in , Similar logic is also used onSubmit , of onSubmit Information about , see also SwiftUI TextField Advanced —— event 、 The focus of 、 keyboard [6].
handler Return result of handled and discarded Will stop url Continue to pass down , The only difference between them is when you explicitly call openURL Will show when .
// callAsFunction The definition of
public struct OpenURLAction {
public func callAsFunction(_ url: URL, completion: @escaping (_ accepted: Bool) -> Void)
}
// handled when accepted by true , discarded when accepted by false
openURL(url) { accepted in
print(accepted ? "Success" : "Failure")
}
Combined with the above introduction , The following code will implement : After clicking the link , Users can choose whether to open the link or copy the link on the pasteboard :
struct ContentView: View {
@Environment(\.openURL) var openURL
@State var url:URL?
var show:Binding<Bool>{
Binding<Bool>(get: { url != nil }, set: {_ in url = nil})
}
let attributedString:AttributedString = {
var fatbobman = AttributedString(" Elbow Swift Notepad ")
fatbobman.link = URL(string: "https://www.fatbobman.com")!
fatbobman.font = .title
var tel = AttributedString(" Phone number ")
tel.link = URL(string:"tel://13900000000")
tel.backgroundColor = .yellow
var and = AttributedString(" and ")
and.foregroundColor = .red
return fatbobman + and + tel
}()
var body: some View {
Form {
Section("NSDataDetector + AttributedString"){
// Use NSDataDetector convert
Text("https://www.fatbobman.com 13900000000 [email protected]".toDetectedAttributedString())
}
}
.environment(\.openURL, .init(handler: { url in
switch url.scheme {
case "tel","http","https","mailto":
self.url = url
return .handled
default:
return .systemAction
}
}))
.confirmationDialog("", isPresented: show){
if let url = url {
Button(" Copy to clipboard "){
let str:String
switch url.scheme {
case "tel":
str = url.absoluteString.replacingOccurrences(of: "tel://", with: "")
default:
str = url.absoluteString
}
UIPasteboard.general.string = str
}
Button(" open URL"){openURL(url)}
}
}
.tint(.cyan)
}
}
openURL_Demo_Recording_iPhone_13_mini_2022-05-20_18.00.15.2022-05-20 18_03_18
summary
Although the main purpose of this article is to introduce SwiftUI Open in view URL Several ways to , But readers should also feel SwiftUI Three years of continuous progress , I believe that in the near future WWDC 2022 It will bring more surprises to developers .
I hope this article can help you .
Reference material
[1] www.fatbobman.com: https://www.fatbobman.com
[2] Download here : https://github.com/fatbobman/BlogCodes/tree/main/openURLinSwiftUI
[3] Swift Playgrounds 4 Entertainment or productivity : https://www.fatbobman.com/posts/swiftPlaygrounds4/
[4] AttributedString—— Not only make the words more beautiful : https://www.fatbobman.com/posts/attributedString/
[5] NSDataDetector: https://developer.apple.com/documentation/foundation/nsdatadetector
[6] SwiftUI TextField Advanced —— event 、 The focus of 、 keyboard : https://fatbobman.com/posts/textfield-event-focus-keyboard/
边栏推荐
- Factory mode and constructor mode
- It's so hot that solar power can't take off? Hello, head
- ZABBIX distributed
- C语言库函数getchar()怎么使用
- Langjing Technology (Trax China) "robot +ai" opens the era of Chinese retail meta universe
- 为 @CloudStorage 添加了类 @Published 的能力
- 面试官:ThreadLocal使用场景有哪些?内存泄露问题如何避免?
- 如何有效进行回顾会议(上)?
- UFIDA BiP CRM new product launch enables large and medium-sized enterprises to grow their marketing
- Excel VBA 免密查看VBE加密代码
猜你喜欢
C # read INI file and key value pair operation

OKR与GRAD

2022年熔化焊接与热切割考题及在线模拟考试

How to reduce the resolution of only 3D camera but not UI camera

2022年安全员-A证操作证考试题库模拟考试平台操作

58子站安居,经纪人营销管理平台登录接口加密逆向

Focus on differentiated product design, intelligent technology efficiency improvement and literacy education around new citizen Finance

Tdengine helps Siemens' lightweight digital solutions

Revised version | target detection: speed and accuracy comparison (faster r-cnn, r-fcn, SSD, FPN, retinanet and yolov3)

Mobile phone scrolling screenshot software recommendation
随机推荐
Hand in hand from 0 to a "Nuggets special attention" Google plug-in, 5000 words detailed vue3 responsive principle, the advantages, disadvantages and choices of several cache read-write schemes, flyin
(function(global,factory){
These three online PS tools should be tried
[Tanabata] Tanabata lonely little frog research edition? The final chapter of Tanabata Festival!
[线程安全问题] 多线程到底可能会带来哪些风险?
9、 Uni popup usage popup effect at the bottom of the drop-down box
[ecmascript6] iterator and generator
数字化转型安全问题频发,山石网科助力数字政府建设
Cv:: mat conversion to qimage error
2022年安全员-A证操作证考试题库模拟考试平台操作
国产数据库的红利还能“吃”多久?
OKR and grad
SwiftUI 布局 —— 尺寸( 上 )
Database optimization understanding these is enough
2022 high altitude installation, maintenance, removal of examination question bank and online simulated examination
一些企业数据平台建设的思考
Core Data 是如何在 SQLite 中保存数据的
九、uni-popup用法 下拉框底部弹窗效果
面试官:ThreadLocal使用场景有哪些?内存泄露问题如何避免?
How to reduce the resolution of only 3D camera but not UI camera