服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - 详解iOS14 Widget 开发相关及易报错地方处理

详解iOS14 Widget 开发相关及易报错地方处理

2021-06-04 16:06奴良 IOS

这篇文章主要介绍了详解iOS14 Widget 开发相关及易报错地方处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

首先了解下如何创建

xcode -> file -> new -> target 找到 widget extension

详解iOS14 Widget 开发相关及易报错地方处理

如果你的 widget 支持用户配置属性,则需要勾选这个(例如天气组件,用户可以选择城市),不支持的话则不用勾选

了解下创建widget后,系统给我们生成的文件内容

下面这个代码是没有勾选 include configuration intent 的地方

provider

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// provider,顾名思义为小组件提供信息得一个struct
struct provider: timelineprovider {
  public typealias entry = simpleentry
  
  // 编辑屏幕时,左上角选择添加小组件时候,第一次展示小组件会走这个方法
  public func snapshot(with context: context, completion: @escaping (simpleentry) -> ()) {
    
  }
 
  // 这个方法内可以进行网络请求,拿到的数据保存在对应的 entry 中,调用 completion 之后会到刷新小组件
  public func timeline(with context: context, completion: @escaping (timeline<entry>) -> ()) {
    // 例如这是一个网络请求
    network.request { data in
      let entry = simpleentry(date: renderdate, data: data)
      let timeline = timeline(entries: [entry], policy: .after(nextrequestdate))
      completion(timeline)
    }
  }
}

entry

官方解释: a type that specifies the date to display a widget, and, optionally, indicates the current relevance of the widget's content.

?
1
2
3
4
5
// 我的理解是就是存储小组件的数据的一个东西
struct simpleentry: timelineentry {
  let date: date
  let data: data
}

placehodlerview

?
1
2
3
4
// 这个是一个默认视图,例如网络请求失败、发生未知错误、第一次展示小组件都会展示这个view
struct placeholderview : view {
  
}

widgetentryview

?
1
2
3
4
// 这个是我们需要布局小组件长什么样子的view
struct staticwidgetentryview : view {
  
}

主入口

?
1
2
3
4
5
6
7
8
9
10
11
12
@main
struct staticwidget: widget {
  private let kind: string = "staticwidget"
 
  public var body: some widgetconfiguration {
    staticconfiguration(kind: kind, provider: provider(), placeholder: placeholderview()) { entry in
      staticwidgetentryview(entry: entry)
    }
    .configurationdisplayname("my widget")
    .description("this is an example widget.")
  }
}

支持多widget样式

?
1
2
3
4
5
6
7
8
9
10
@main
struct mainwidgets: widgetbundle {
 
  @widgetbundlebuilder
  var body: some widget {
    widget1()
    widget2()
  }
 
}

勾选 include configuration intent 之后可能出错的地方

如果你的app中设置了 class prefix 这下面这个 configurationintent.self 则需要加上对应的前缀

例如前缀是 xy 则需要修改为 xyconfigurationintent.self

?
1
2
3
4
5
6
7
8
9
10
11
12
@main
struct mainwidget: widget {
  private let kind: string = "mainwidget"
 
  public var body: some widgetconfiguration {
    intentconfiguration(kind: kind, intent: xyconfigurationintent.self, provider: provider(), placeholder: placeholderview()) { entry in
      intentwidgetentryview(entry: entry)
    }
    .configurationdisplayname("my widget")
    .description("this is an example widget.")
  }
}

处理widget点击事件

widget 支持三种显示方式,分别是 systemsmall 、 systemmedium 、 systemlarge
small 样式只能用 widgeturl 处理

?
1
2
3
4
5
6
7
8
9
@viewbuilder
var body: some view {
  zstack {
    avatarview(entry.character)
      .widgeturl(url)
      .foregroundcolor(.white)
  }
  .background(color.gamebackground)
}

medium 和 large 可以用 link 或者 widgeturl 处理,我们看到里面有四个相同的view,即左边图片,右边文字的,这个view代码如下(link方式)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct recipeview: view {
  let recipe: recipemodel
  
  var body: some view {
    link(destination: url(string: "你的网址")!) {
      hstack {
        webimageview(imageurl: recipe.squareimageurl)
          .frame(width: 65, height: 65)
        
        text(recipe.adjname + recipe.name)
          .font(.footnote)
          .bold()
          .foregroundcolor(.black)
          .linelimit(3)
      }
    }
  }
}

添加 link 或 widgeturl 后,点击每个 recipeview 都会触发事件,这时候你需要在主项目中的 appdelegate 中的如下方法进行处理

?
1
2
3
func application(_ app: uiapplication, open url: url, options: [uiapplication.openurloptionskey : any] = [:]) -> bool {
    
}

关于widget中加载网络图片的时机

当我们在func timeline(withcompletion)这个方法中请求到数据拿到图片链接后,必须同步把图片解析出来,否则直接让对应的widgetview去load url 是加载不出来的

正确的写法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct model {
 ...
 let image: uiimage
}
 
func timeline(with context: context, completion: @escaping (timeline<lfplanentry>) -> ()) {
  network.request { data in
    // 解析图片
    var image: uiimage? = nil
    if let imagedata = try? data(contentsof: url) {
      image = uiimage(data: imagedata)
    }
    let model = model(image: image ?? defalutimage) // 这里给个默认图片
    let entry = simpleentry(date: entrydate, data: model)
    let timeline = timeline(entries: [entry], policy: .atend)
    completion(timeline)
  }
}
 
struct widgetview: view {
  
  let model: model
 
  @viewbuilder
  var body: some view {
    image(uiimage: model.image)
          .resizable()
  }
 
}

错误的写法(直接丢url给view去加载)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct widgetview : view {
  
  let model: model
 
  @state private var remoteimage : uiimage? = nil
  
  let defaultimage = uiimage(named: "default")!
  
  var body: some view {
    image(uiimage: self.remoteimage ?? defaultimage)
      .onappear(perform: fetchremoteimage)
  }
  
  func fetchremoteimage() {
    guard let url = url(string: model.url) else { return }
    urlsession.shared.datatask(with: url){ (data, response, error) in
      if let image = uiimage(data: data!){
        self.remoteimage = image
      } else {
        print(error ?? "")
      }
    }.resume()
  }
}

基于我们的app做出来的简单效果图

详解iOS14 Widget 开发相关及易报错地方处理

widget相关资料

widgets

creating a widget extension

keeping a widget up to date

making a configurable widget

到此这篇关于详解ios14 widget 开发相关及易报错地方处理的文章就介绍到这了,更多相关ios14 widget开发内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.jianshu.com/p/b0d6a14442fe

延伸 · 阅读

精彩推荐
  • IOSiOS逆向教程之logify跟踪方法的调用

    iOS逆向教程之logify跟踪方法的调用

    这篇文章主要给大家介绍了关于iOS逆向教程之logify跟踪方法调用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学...

    Mr.Guo11472021-04-28
  • IOSiOS中时间与时间戳的相互转化实例代码

    iOS中时间与时间戳的相互转化实例代码

    这篇文章主要介绍了iOS中时间与时间戳的相互转化实例代码,非常具有实用价值,需要的朋友可以参考下。...

    张无忌!4812021-03-09
  • IOSIOS网络请求之AFNetWorking 3.x 使用详情

    IOS网络请求之AFNetWorking 3.x 使用详情

    本篇文章主要介绍了IOS网络请求之AFNetWorking 3.x 使用详情,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    总李写代码6892021-03-04
  • IOSiOS常见的几个修饰词深入讲解

    iOS常见的几个修饰词深入讲解

    这篇文章主要给大家介绍了关于iOS常见的几个修饰词的相关资料,iOS修饰词包括assign、weak、strong、retain、copy、nonatomic、atomic、readonly、readwrite,文中通过示...

    郡王丶千夜7422021-05-10
  • IOSiOS APP实现微信H5支付示例总结

    iOS APP实现微信H5支付示例总结

    这篇文章主要介绍了iOS APP实现微信H5支付示例总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    一张小A11332021-06-01
  • IOSiOS10 Xcode8适配7个常见问题汇总

    iOS10 Xcode8适配7个常见问题汇总

    这篇文章主要为大家详细汇总了iOS10 Xcode8适配7个常见问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    索马里猫10332021-02-01
  • IOSxcode8提交ipa失败无法构建版本问题的解决方案

    xcode8提交ipa失败无法构建版本问题的解决方案

    xcode升级到xcode8后发现构建不了新的版本。怎么解决呢?下面小编给大家带来了xcode8提交ipa失败无法构建版本问题的解决方案,非常不错,一起看看吧...

    Cinna丶7542021-02-03
  • IOS谈一谈iOS单例模式

    谈一谈iOS单例模式

    这篇文章主要和大家谈一谈iOS中的单例模式,单例模式是一种常用的软件设计模式,想要深入了解iOS单例模式的朋友可以参考一下...

    彭盛凇11872021-01-19