{"id":4991,"date":"2022-02-18T15:00:52","date_gmt":"2022-02-18T07:00:52","guid":{"rendered":"http:\/\/123.57.164.21\/?p=4991"},"modified":"2022-02-18T15:00:52","modified_gmt":"2022-02-18T07:00:52","slug":"swiftui-geometryeffect","status":"publish","type":"post","link":"https:\/\/92it.top\/?p=4991","title":{"rendered":"SwiftUI GeometryEffect"},"content":{"rendered":"\n<h5 class=\"wp-block-heading\"><strong>GeometryEffect<\/strong><\/h5>\n\n\n\n<p><strong>GeometryEffect<\/strong>\u00a0\u662f\u4e00\u4e2a\u9075\u5faa\u00a0<strong>Animatable<\/strong>\u00a0\u548c\u00a0<strong>ViewModifier<\/strong>\u00a0\u534f\u8bae\u7684\u534f\u8bae\uff0c\u5b83\u53ef\u4ee5\u5bf9\u89c6\u56fe\u7684\u5750\u6807\u8fdb\u884c\u53d8\u5316\uff0c\u5e76\u4e14\u4e0d\u4f1a\u5f71\u54cd\u5230\u8be5\u89c6\u56fe\u7684\u7236\u89c6\u56fe\u548c\u5b50\u89c6\u56fe\u7684\u5e03\u5c40\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">func effectValue(size: CGSize) -> ProjectionTransform\n<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-6.png\" alt=\"\" class=\"wp-image-4992\" width=\"308\" height=\"131\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-6.png 542w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-6-300x127.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-6-230x98.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-6-350x149.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-6-480x204.png 480w\" sizes=\"(max-width: 308px) 100vw, 308px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/123.57.164.21\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-7.png\" alt=\"\" class=\"wp-image-4993\" width=\"274\" height=\"108\" srcset=\"https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-7.png 518w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-7-300x118.png 300w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-7-230x91.png 230w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-7-350x138.png 350w, https:\/\/92it.top\/wp-content\/uploads\/2022\/02\/\u56fe\u7247-7-480x189.png 480w\" sizes=\"(max-width: 274px) 100vw, 274px\" \/><\/figure><\/div>\n\n\n\n<p>\u5b83\u8fd4\u56de\u7684\u662f\u53d8\u5316\u6548\u679c\u7684\u5f53\u524d\u503c\uff0c\u6bd4\u5982\u793a\u4f8b\u6240\u793a\u7684\uff0c\u6211\u4eec\u9700\u8981\u5b9e\u73b0\u4e00\u4e2a\u7ffb\u8f6c\u6548\u679c\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct FlipEffect: GeometryEffect {\n  \/\/\/ \u662f\u5426\u5df2\u7ffb\u8f6c\n  @Binding var flipped: Bool\n  \/\/\/ \u7ffb\u8f6c\u89d2\u5ea6\n  var angle: CGFloat\n  \n  var animatableData: CGFloat {\n    get { angle }\n    set { angle = newValue }\n  }\n  \n  func effectValue(size: CGSize) -> ProjectionTransform {\n    DispatchQueue.main.async {\n      \/\/ \u83b7\u53d6\u5f53\u524d\u53d8\u5316\u7684\u72b6\u6001\n      \/\/ \u901a\u8fc7\u7ed1\u5b9a\u503c\u5c06\u7ffb\u8f6c\u72b6\u6001\u56de\u4f20\u7ed9\u89c6\u56fe\n      flipped = angle >= .pi * 0.5\n    }\n    \/\/ \u8fd4\u56de\u7684\u89c6\u56fe\u53d8\u5316\u6548\u679c,\u8fd9\u91cc\u662f3D\u7ffb\u8f6c\u6548\u679c\n    var transform3d = CATransform3DMakeRotation(angle, 0, 1, 0)\n    transform3d = CATransform3DTranslate(transform3d, -size.width * 0.5, 0, 0)\n    return ProjectionTransform(transform3d)\n  }\n}\n<\/pre>\n\n\n\n<p>\u7136\u540e\u6211\u4eec\u901a\u8fc7 modifier \u8c03\u7528\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@State private var angle: CGFloat = 0\n@State private var flipped = false\nprivate let circleSize: CGFloat = 80\nvar randomString: String {\n  Bool.random() ? \"\u2764\ufe0f\" : \"\ud83d\ude2d\"\n}\n\n\nVStack {\n  HStack(spacing: 20) {\n    circle\n    circle\n    circle\n  }\n  \n  HStack(spacing: 20) {\n    Button(\"\u7ffb\u8f6c\") {\n      withAnimation(.spring(response: 0.5, \n                            dampingFraction: 0.5, \n                            blendDuration: 0.5) {\n        angle += flipped ? -.pi : .pi\n      }\n    }\n    .padding()\n    \n    Button(\"\u6162\u653e\") {\n      withAnimation(.easeInOut(duration: 3)) {\n        angle += flipped ? -.pi : .pi\n      }\n    }\n    .padding()\n  }\n}\n  \nvar circle: some View {\n  ZStack {\n    Circle()\n      .fill(Color.blue)\n      .frame(width: circleSize, height: circleSize)\n    \n    Text(flipped ? randomString : \"?\")\n      .foregroundColor(.white)\n      .font(.largeTitle)\n  }\n  .modifier(FlipEffect(flipped: $flipped, angle: angle))\n  .offset(x: circleSize * 0.5, y: 0)\n}<\/pre>\n\n\n\n<p>\u53e6\u5916\uff0c<strong>GeometryEffect<\/strong>\u00a0\u8fd8\u6709\u4e00\u4e2a\u53ef\u9009\u7684\u65b9\u6cd5\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">func ignoredByLayout() -> _IgnoredByLayoutEffect&lt;Self>\n<\/pre>\n\n\n\n<p>\u4e00\u822c\u6765\u8bb2\uff0c\u5f53\u6211\u4eec\u5bf9\u89c6\u56fe\u505a\u53d8\u6362\u7684\u65f6\u5019\uff0c\u5b83\u7684\u5e03\u5c40\u4fe1\u606f\uff08\u5750\u6807\u3001\u5c3a\u5bf8\u7b49\uff09\u4f1a\u8ddf\u7740\u53d8\u5316\uff0c\u5982\u679c\u6211\u4eec\u4e0d\u5e0c\u671b\u5982\u6b64\uff0c\u5c31\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\u65b9\u6cd5\uff0c\u5b83\u4e0d\u4f1a\u6539\u53d8\u89c6\u56fe\u7684\u5e03\u5c40\u4fe1\u606f\uff0c\u4f46\u662f\u52a8\u753b\u6548\u679c\u5e76\u4e0d\u53d7\u5f71\u54cd\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<h5 class=\"wp-block-heading\">matchedGeometryEffect<\/h5>\n\n\n\n<p><strong>matchedGeometryEffect<\/strong>\u00a0\u662f iOS 14 \u65b0\u589e\u7684 modifier\uff0c\u4f7f\u7528\u7b80\u5355\uff0c\u529f\u80fd\u5f3a\u5927\u3002\u6211\u4eec\u76f4\u63a5\u7ed3\u5408\u793a\u4f8b\u548c\u4ee3\u7801\u6765\u770b\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@State private var changed = false\n@Namespace private var ns\n\nVStack {\n  if changed {\n    VStack {\n      Image(\"icon\")\n        .cornerRadius(10)\n        .matchedGeometryEffect(id: \"icon\", in: ns)\n      HStack {\n        Text(\"\u5982\u679c\u4f60\u559c\u6b22 Eul\uff0c\u8bf7\u8bc4\u4ef7\/\u5206\u4eab\")\n          .font(.subheadline)\n        Spacer()\n        Link(destination: URL(string:\n\"https:\/\/apps.apple.com\/cn\/app\/eul\/id154199\n          Label(\"\", systemImage: \"square.and.arrow.up\n        }\n      }\n      .matchedGeometryEffect(id: \"content\", in: ns)\n    }\n  } else {\n    HStack {\n      Image(\"icon\")\n        .cornerRadius(10)\n        .matchedGeometryEffect(id: \"icon\", in: ns)\n      HStack {\n        Text(\"\u5982\u679c\u559c\u6b22 Eul\uff0c\u8bf7\u8bc4\u4ef7\/\u5206\u4eab\")\n          .font(.subheadline)\n        Spacer()\n        Link(destination: URL(string:\n\"https:\/\/apps.apple.com\/cn\/app\/eul\/id154199\n          Label(\"\", systemImage: \"square.and.arrow.up\n        }\n      }\n      .matchedGeometryEffect(id: \"content\", in: ns)\n    }\n  }\n  \n  Button(\"\u70b9\u6211\") {\n    withAnimation(.spring()) {\n      changed.toggle()\n    }\n  }\n  .padding()\n}\n<\/pre>\n\n\n\n<p>\u901a\u8fc7\u4ee3\u7801\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230\uff0c\u52a8\u753b\u524d\u540e\uff0c\u89c6\u56fe\u7684\u5185\u5bb9\u5e76\u6ca1\u6709\u53d8\u5316\uff0c\u53ea\u662f\u5e03\u5c40\u53d1\u751f\u4e86\u53d8\u5316\uff0c\u9488\u5bf9\u8fd9\u6837\u7684\u573a\u666f\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7&nbsp;<strong>matchedGeometryEffect<\/strong>&nbsp;\u7ed9\u5b83\u6dfb\u52a0\u5e73\u6ed1\u7684\u52a8\u753b\u6548\u679c\u3002<\/p>\n\n\n\n<p><strong>matchedGeometryEffect<\/strong>&nbsp;\u9700\u8981\u6807\u8bc6\u7b26&nbsp;<strong>id<\/strong>&nbsp;\u6765\u540c\u6b65\u89c6\u56fe\u7684\u5e03\u5c40\uff0c<strong>id<\/strong>&nbsp;\u662f\u5b9a\u4e49\u5728\u547d\u540d\u7a7a\u95f4&nbsp;<strong>namespace<\/strong>&nbsp;\u4e2d\u7684\uff0c\u901a\u5e38\u6211\u4eec\u53ea\u9700\u8981\u6307\u5b9a\u8fd9\u4e24\u4e2a\u53c2\u6570\u5c31\u8db3\u591f\u4e86\u3002<\/p>\n\n\n\n<p><strong>matchedGeometryEffect<\/strong>&nbsp;\u65b9\u6cd5\u8fd8\u63d0\u4f9b\u4ee5\u4e0b\u53c2\u6570\uff0c\u4f5c\u4e86\u89e3\uff1a<\/p>\n\n\n\n<ul><li><strong>properties<\/strong>&nbsp;: \u4ece source view \u590d\u5236\u7684\u5c5e\u6027\uff0c\u9ed8\u8ba4\u662f frame\uff0c\u8fd8\u53ef\u4f7f\u7528 position\u3001size<\/li><li><strong>anchor<\/strong>&nbsp;: \u951a\u70b9\uff0c\u9ed8\u8ba4\u662f center<\/li><li><strong>isSource<\/strong>&nbsp;: \u662f\u5426\u4f5c\u4e3a\u6e90\u89c6\u56fe\uff0c\u9ed8\u8ba4\u662f true<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>GeometryEffect GeometryEffect\u00a0\u662f\u4e00\u4e2a\u9075\u5faa\u00a0Animatable\u00a0\u548c\u00a0ViewMo [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/4991"}],"collection":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4991"}],"version-history":[{"count":3,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/4991\/revisions"}],"predecessor-version":[{"id":4996,"href":"https:\/\/92it.top\/index.php?rest_route=\/wp\/v2\/posts\/4991\/revisions\/4996"}],"wp:attachment":[{"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/92it.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}