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

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布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25