SVG ใน SwiftUI: เพิ่มแอสเซ็ตและควบคุมสี
เพิ่ม SVG ในชุดภาพของ Xcode โหลดด้วยชื่อแอสเซ็ต และเลือกการเรนเดอร์แบบ original หรือ template ตรวจสี ระยะว่าง และแอปที่ส่งมอบในขนาดใช้งานจริง
ในหน้านี้
สำหรับ SVG แบบคงที่ที่รวมมากับแอป SwiftUI ให้วางงานภาพในแค็ตตาล็อกแอสเซ็ตของ Xcode และโหลดภาพด้วยชื่อแอสเซ็ต จากนั้นตัดสินใจว่าจะเก็บสีต้นฉบับหรือเปลี่ยนเป็นรูปเงาที่ลงสีได้ Apple เพิ่มแอสเซ็ตภาพ SVG ใน Xcode 12 โดย บันทึกประจำรุ่น ระบุการคงรูปแบบเวกเตอร์สำหรับเป้าหมายการใช้งาน iOS 13, iPadOS 13 และ macOS 10.15 ขึ้นไป
ขั้นตอนผ่านแค็ตตาล็อกนี้ต่างจากการดาวน์โหลดไฟล์ SVG ขณะแอปทำงาน และต่างจากการสร้าง SF Symbol แบบกำหนดเอง เลือกวิธีส่งมอบก่อนแก้งานภาพหรือเพิ่มแพ็กเกจเรนเดอร์
เลือกวิธีสำหรับภาพนี้โดยเฉพาะ
SVG เป็นไฟล์ต้นทาง วิธีที่แอปรับและใช้ไฟล์นั้นเป็นตัวกำหนดขั้นตอนถัดไป
| สิ่งที่ต้องการ | วิธีเริ่มต้น | สิ่งที่ต้องตรวจ |
|---|---|---|
| โลโก้หรือภาพประกอบคงที่ที่รวมกับแอป | ชุดภาพปกติในแค็ตตาล็อกแอสเซ็ต | ชื่อแอสเซ็ต สี ขอบเขต และผลการบิลด์ |
| ไฟล์ SVG ที่รับขณะทำงาน | โซลูชันเรนเดอร์ SVG ที่รองรับโดยตรง | คุณสมบัติที่ตัวเรนเดอร์รองรับ และพฤติกรรมการโหลด/ข้อผิดพลาด |
| รูปทรงที่คุณควบคุมเรขาคณิตใน SwiftUI | โค้ด Shape/Path ในตัว | การแปลงพาธ สัดส่วน และการกำหนดรูปแบบ |
| สัญลักษณ์กำหนดเองที่มีน้ำหนักและการจัดแนวคล้ายข้อความ | ขั้นตอนใช้แม่แบบ SF Symbols | รูปแบบย่อย เส้นนำ ข้อมูลกำกับ และการตรวจสอบที่จำเป็น |
ตัวอย่างนี้ใช้วิธีแรก ถ้วยเล็กสองสีช่วยให้สังเกตข้อผิดพลาดสองอย่างได้ง่าย: สีคอรัลของไอน้ำหายไป และช่องว่างในหูถ้วยถูกเติม ทั้งสองปัญหาไม่ต้องใช้ภาพประกอบซับซ้อนเพื่อวินิจฉัย
คู่มือเตรียมชุด UI อธิบายงานที่กว้างกว่าในการทำให้ทั้งชุดสอดคล้องกัน ในที่นี้ คำถามคือ SVG ที่ยอมรับแล้วหนึ่งไฟล์ไปถึง Image ของ SwiftUI ได้อย่างไร
เตรียมต้นฉบับเล็กที่มีจุดตรวจมองเห็นได้
บันทึกตัวอย่างต้นฉบับนี้เป็น CupMark.svg:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<path d="M12 26H43V45Q43 54 34 54H21Q12 54 12 45Z"
fill="#147D73"/>
<path d="M43 30H48Q55 30 55 37Q55 44 48 44H43"
fill="none" stroke="#147D73" stroke-width="5"/>
<path d="M24 19Q18 14 25 8M35 19Q29 14 36 8"
fill="none" stroke="#EB8067" stroke-width="4" stroke-linecap="round"/>
</svg>ถ้วยเป็นสีเขียวอมฟ้า เส้นไอน้ำสองเส้นเป็นสีคอรัล และพื้นที่ในหูถ้วยว่างอยู่ เก็บคุณสมบัติทั้งสามไว้ในรายการตรวจ SVG นี้ไม่มีข้อความ ภาพภายนอก ฟิลเตอร์ หรือสคริปต์ จึงเป็นไฟล์เริ่มต้นขนาดเล็กสำหรับทดลองกับแค็ตตาล็อก
สำหรับงานของคุณ ให้ตรวจต้นฉบับก่อนนำเข้า พื้นที่ว่างบนพื้นที่ภาพมากเกินไปทำให้ไอคอนดูเล็กแม้ว่าวิวจะมีขนาดถูกต้อง สี่เหลี่ยมพื้นหลังสีขาวกลายเป็นส่วนหนึ่งของรูปเงาในโหมด template ภาพถ่ายที่ฝังอยู่ยังเป็นเนื้อหาคนละชนิดกับพาธรอบ ๆ วิธีตรวจแรสเตอร์ที่ฝัง ช่วยแยกสิ่งเหล่านี้
เก็บไฟล์หลักที่แก้ไขได้ไว้นอกสำเนาสำหรับส่งมอบในแอป หากไอคอนมีตัวอักษร ให้จัดการฟอนต์หรือวิธีแปลงเป็นเส้นขอบที่ต้องการในไฟล์หลัก ดู ขั้นตอนแก้ฟอนต์ SVG เปลี่ยน การเปลี่ยนรูปแบบข้อความของ SwiftUI ไม่ทดแทนการตรวจตัวอักษรภายในภาพ

เพิ่มเป็นชุดภาพปกติ
เปิดแค็ตตาล็อกแอสเซ็ตของแอป ซึ่งมักชื่อ Assets.xcassets เพิ่มชุดภาพใหม่และตั้งชื่อ CupMark ลาก SVG ลงช่องภาพที่เหมาะสม คู่มือแค็ตตาล็อกแอสเซ็ต ของ Apple อธิบายการสร้างชุด นำเข้าทรัพยากร และกำหนดรูปแบบย่อยผ่าน Attributes inspector
ใช้ชุดภาพสำหรับตัวอย่างนี้ อย่าเลือกขั้นตอนภาพสัญลักษณ์เพียงเพราะต้นทางลงท้ายด้วย .svg
หลังนำเข้า ตรวจภาพตัวอย่างในแค็ตตาล็อกและข้อความวินิจฉัยจากการบิลด์ ยืนยันว่าแค็ตตาล็อกอยู่ใน target ของแอปที่ต้องใช้ หากการตั้งค่าแอสเซ็ตมีรูปแบบย่อยตามแพลตฟอร์มหรือรูปลักษณ์ ตรวจว่าภาพที่ต้องการอยู่ในการตั้งค่าที่เกี่ยวข้อง แทนที่จะคิดว่าภาพตัวอย่างแทนทุกการตั้งค่า
ชื่อ CupMark คือชื่อทรัพยากรภาพที่ใช้ด้านล่าง ไม่ใช่ URL ดาวน์โหลดหรือพาธไปยัง SVG ต้นฉบับในโฟลเดอร์ออกแบบ ตัวเริ่มต้น Image ของ Apple ค้นหาทรัพยากรด้วยชื่อใน bundle โดยค่าเริ่มต้นคือ bundle หลัก หากภาพอยู่ใน bundle ทรัพยากรอื่น ให้ระบุ bundle นั้นอย่างตั้งใจ
แยกชื่อไฟล์กับชื่อแอสเซ็ตให้ชัดในบันทึกส่งมอบ เพื่อนร่วมทีมเปลี่ยนชื่อชุดแอสเซ็ตได้โดยไม่เปลี่ยนชื่อไฟล์ออกแบบต้นฉบับ และโค้ดต้องใช้ชื่อทรัพยากรที่โหลดจริง
เปรียบเทียบการเรนเดอร์ original กับ template
ใช้วิวนี้หลังเพิ่มชุดภาพ CupMark:
import SwiftUI
struct CupComparison: View {
var body: some View {
HStack(spacing: 24) {
Image("CupMark")
.renderingMode(.original)
.resizable()
.scaledToFit()
.frame(width: 48, height: 48)
.accessibilityLabel("Cup with rising steam")
Image("CupMark")
.renderingMode(.template)
.resizable()
.scaledToFit()
.frame(width: 48, height: 48)
.foregroundStyle(Color.blue)
.accessibilityLabel("Cup with rising steam")
}
.padding()
}
}ภาพด้านซ้ายขอการเรนเดอร์แบบ original อย่างชัดเจน ภาพด้านขวาขอแบบ template และกำหนดสีน้ำเงินเป็นรูปแบบสีด้านหน้า เอกสารการเรนเดอร์ template ของ Apple นิยามโหมดนี้ว่าพิกเซลที่ไม่โปร่งใสรับสีด้านหน้า เป็นการจัดการรูปเงา ไม่ใช่คำสั่งเปลี่ยนสีพาธ SVG เพียงชิ้นเดียว
สำหรับถ้วย หมายความว่าเวอร์ชันขวาควรมีทั้งไอน้ำและถ้วยสีน้ำเงิน ความแตกต่างระหว่างคอรัลกับเขียวอมฟ้าหายไปโดยตั้งใจ ช่องเปิดหูถ้วยควรยังว่าง หากแอปต้องเปลี่ยนไอน้ำแยกจากถ้วย ให้เลือกโครงสร้างส่งมอบที่เปิดให้ใช้ส่วนเหล่านั้นแยกกัน แทนที่จะคาดหวังให้ภาพ template เดียวกำหนดรูปแบบรายพาธได้
ตัวปรับเหล่านี้ยังระบุการเลือกขนาดอย่างชัดเจน resizable() เปิดพฤติกรรมปรับขนาดภาพ และ scaledToFit() รักษาอัตราส่วนภายในกรอบ 48 พอยต์ กรอบวิวกับพื้นที่ภาพของงานเองเป็นขอบเขตคนละส่วน พื้นที่ว่างเกินภายใน SVG ยังอยู่ในต้นทาง
นี่เป็นตัวอย่างตามเอกสารให้ทดลองในโครงการ ไม่ใช่รายงานผลทดสอบการเรนเดอร์บนแพลตฟอร์มจริง ตรวจแอปที่บิลด์จริง รวมทั้งขนาดเล็กที่สุดที่ตั้งใจใช้เครื่องหมาย ภาพตัวอย่างชัดที่ 48 พอยต์ไม่ได้ยืนยันว่าเส้นไอน้ำทั้งสองยังมีประโยชน์ที่ 16 พอยต์
วินิจฉัยผลที่เห็นก่อนเปลี่ยนไฟล์
ภาพหาย สีเปลี่ยน และรูปเงาขนาดเล็กไม่เหมาะต้องแก้คนละวิธี
| อาการ | สิ่งที่ตรวจอันดับแรก | ขั้นตอนถัดไปที่มีประโยชน์ |
|---|---|---|
| ไม่มีภาพปรากฏ | ชื่อทรัพยากร bundle target และข้อความวินิจฉัยการบิลด์แค็ตตาล็อก | แก้การค้นหาหรือนำเข้าก่อนแก้พาธ |
| ทุกส่วนเป็นสีเดียว | การเรนเดอร์ original หรือ template | ใช้ original สำหรับงานหลายสีที่คงที่ |
| สีที่ใส่เติมเป็นสี่เหลี่ยมใหญ่ | พื้นหลังทึบในต้นฉบับ | ลบรูปทรงพื้นหลังที่ไม่ตั้งใจในไฟล์หลัก |
| เครื่องหมายดูเล็กเกินไป | พื้นที่ว่างภายในพื้นที่ภาพ SVG | แก้พื้นที่ภาพแล้วส่งออกใหม่ |
| ไอน้ำหรือช่องเปิดแคบไม่ชัด | ขนาดแสดงผลสุดท้ายและรายละเอียดต้นฉบับ | ลดรายละเอียดอย่างตั้งใจและตรวจเวอร์ชันเล็ก |
| คุณสมบัติหนึ่งต่างจากโปรแกรมออกแบบ | คุณสมบัติ SVG นั้นและข้อความวินิจฉัยตัวนำเข้า | ทดสอบสำเนาส่งมอบที่เรียบง่ายขึ้นหรือเลือกรูปแบบอื่นที่รองรับ |
เปลี่ยนทีละชั้น หากต้นฉบับมีช่องเปิดถูกต้องอยู่แล้ว การสร้างพาธใหม่ไม่แก้ชื่อแอสเซ็ตที่สะกดผิด หากค้นหาภาพได้แต่โหมด template ลบความแตกต่างของสี การเพิ่มสีใน SVG ไม่เปลี่ยนโหมดเรนเดอร์ที่เลือก
สำหรับไอคอนข้างข้อความที่มองเห็น ให้ตรวจชื่อสำหรับการเข้าถึงในบริบทของตัวควบคุมทั้งหมด ตัวอย่างใส่คำอธิบายให้แต่ละภาพเปรียบเทียบ ภาพตกแต่งที่ซ้ำข้างตัวควบคุมซึ่งมีชื่อแล้วอาจต้องจัดการการเข้าถึงต่างออกไป อย่านำป้ายกำกับจากวิวเปรียบเทียบไปใช้ทุกตำแหน่งโดยไม่พิจารณา
แยกการตัดสินใจเรื่อง SVG ขณะทำงานกับ SF Symbols
ภาพแค็ตตาล็อกที่เรียกด้วยชื่อไม่ใช่ API ดึงและแยกวิเคราะห์ SVG XML ใด ๆ หากไฟล์มาถึงหลังบิลด์แอป ให้เลือกตัวเรนเดอร์ที่จัดการอินพุตนั้นโดยตรง เช่น README ของโครงการ SVGView อธิบายตัวแยกวิเคราะห์และเรนเดอร์ SVG ที่เขียนใน SwiftUI ประเมินคุณสมบัติ SVG ที่ไฟล์จริงใช้ เป้าหมายรองรับอย่างกว้างขวางของแพ็กเกจไม่ได้พิสูจน์ว่าอินพุตทั้งชุดของคุณเรนเดอร์ถูกต้อง
ให้การโหลด ความล้มเหลว และพฤติกรรมต่อไฟล์ที่ไม่รองรับเป็นส่วนหนึ่งของคุณสมบัติขณะทำงานนั้น อย่าเพิ่มแพ็กเกจเพียงเพราะคำตอบเก่าระบุว่า SwiftUI ใช้ภาพ SVG ไม่ได้ หากสิ่งที่ต้องการเป็นภาพคงที่ซึ่งวิธีแค็ตตาล็อกแอสเซ็ตรองรับอยู่แล้ว
SF Symbols กำหนดเองมีข้อกำหนดต้นทางต่างออกไป Apple อธิบาย ขั้นตอนสร้างและตรวจสอบด้วยแม่แบบ รวมทั้งรูปแบบย่อยของสัญลักษณ์และข้อมูลการจัดแนว SVG ถ้วยปกติไม่ได้มีคุณสมบัติเหล่านั้นเพียงเพราะวางในชุดภาพ ใช้ขั้นตอนนั้นเมื่อแอปต้องการพฤติกรรมสัญลักษณ์ และเก็บโครงสร้างแม่แบบที่จำเป็นไว้
ควรตรวจรูปแบบส่งมอบของแต่ละแพลตฟอร์มแยกกัน หากงานเดียวกันจะไป Android ด้วย ให้ทำตาม คู่มือส่งมอบ VectorDrawable การที่ตัวนำเข้าของแพลตฟอร์มหนึ่งยอมรับไม่ได้พิสูจน์ว่าอีกแพลตฟอร์มจะยอมรับ
เมื่อไอคอนเหลือเพียง PNG
หากต้นฉบับแก้ไขได้หายไปและ PNG เป็นไอคอนเรียบง่าย ตัวแปลง PNG เป็น SVG ของ PerfectVector ช่วยเตรียมงานภาพสำหรับประเมินในขั้นตอนนี้ได้ ครอบภาพให้เหลือไอคอน ตรวจภาพตัวอย่างหาช่องเปิดที่หาย รายละเอียดที่รวมกัน และรูปทรงพื้นหลังที่ไม่ต้องการ แล้วเปรียบเทียบกับต้นฉบับ ดาวน์โหลด SVG ที่ยอมรับแล้วและทดสอบผ่านการตรวจชุดภาพกับโหมดเรนเดอร์เดียวกัน
ใช้เวกเตอร์ต้นฉบับเมื่อมี เก็บภาพถ่ายและภาพที่มีเอฟเฟกต์มากเป็นแรสเตอร์เมื่อรักษารูปลักษณ์ได้ดีกว่า การแปลงเป็นเวกเตอร์เตรียมรูปทรง ไม่ได้คอมไพล์แค็ตตาล็อก Xcode เลือก bundle ทรัพยากร หรือสร้างแม่แบบ SF Symbols ที่มีรูปแบบย่อยครบตามข้อกำหนด
ก่อนส่งมอบแอสเซ็ต บันทึกชื่อในแค็ตตาล็อก พฤติกรรม original/template ที่ต้องการ ขนาดเล็กที่สุดที่เหมาะแก่การมองเห็น และไฟล์ต้นทางสำหรับสร้างใหม่ ทดสอบพื้นหลังสว่างและมืดกับรูปแบบรูปลักษณ์ที่รองรับในแอป คู่มืองานภาพในบล็อก อธิบายการเตรียมต้นทางก่อนขั้นตอนส่งมอบนี้
คำถามที่พบบ่อย
SwiftUI ใช้ SVG จากแค็ตตาล็อกแอสเซ็ตได้หรือไม่? ได้ Xcode รองรับแอสเซ็ตภาพ SVG เพิ่มไฟล์ในชุดภาพปกติแล้วโหลดทรัพยากรที่มีชื่อด้วย Image ตรวจเป้าหมายการใช้งานและการบิลด์แค็ตตาล็อกจริง แทนการถือว่านี่คือการรองรับไฟล์ SVG ใด ๆ ขณะทำงาน
ทำไม SVG จึงกลายเป็นสีเดียว? ตรวจโหมดเรนเดอร์ แบบ template ใช้ส่วนภาพที่มองเห็นเป็นรูปเงาซึ่งรับสีด้านหน้า ใช้แบบ original เมื่อต้องเก็บความแตกต่างของสีต้นฉบับ
Image โหลด SVG จาก URL เว็บได้หรือไม่? ตัวเริ่มต้น Image แบบชื่อเป็นการค้นหาทรัพยากร ไม่ใช่ตัวแยกวิเคราะห์ SVG จาก URL ไฟล์ SVG ขณะทำงานต้องมีขั้นตอนโหลดและเรนเดอร์ที่เหมาะสม ซึ่งตรวจด้วยอินพุตจริงของคุณ
ชุดภาพ SVG เหมือน SF Symbol กำหนดเองหรือไม่? ไม่ สัญลักษณ์กำหนดเองใช้แม่แบบที่มีโครงสร้าง รูปแบบย่อย ข้อมูลจัดแนว และการตรวจสอบตามข้อกำหนด ชุดภาพ SVG ปกติไม่ได้ให้คุณสมบัติสัญลักษณ์เหล่านั้นโดยอัตโนมัติ
แหล่งอ้างอิง
- Apple — บันทึกประจำรุ่น Xcode 12 — การรองรับแอสเซ็ตภาพ SVG และเป้าหมายการใช้งานที่คงเวกเตอร์ตามเอกสาร
- Apple — จัดการแอสเซ็ตด้วยแค็ตตาล็อกแอสเซ็ต — ชุดแอสเซ็ต ช่องนำเข้า และรูปแบบย่อย
- Apple — Image init(_:bundle:) — การค้นหาทรัพยากรที่มีชื่อและ bundle
- Apple — Image.TemplateRenderingMode — โหมดเรนเดอร์ original และ template
- Apple — resizable(capInsets:resizingMode:) — พฤติกรรมปรับขนาดภาพอย่างชัดเจน
- Apple — scaledToFit() — การปรับให้พอดีโดยรักษาอัตราส่วน
- Apple — สร้างภาพสัญลักษณ์กำหนดเองสำหรับแอป — แม่แบบสัญลักษณ์กำหนดเอง รูปแบบย่อย และการตรวจสอบ
- Exyte — SVGView — โซลูชันแยกสำหรับแยกวิเคราะห์และเรนเดอร์ SVG ใน SwiftUI
ตรวจไอคอนหนึ่งชิ้นในขนาดและโหมดสีที่ตั้งใจใช้ก่อนนำเข้าทั้งชุด หากเหลือเพียง PNG ให้ เตรียม SVG สำหรับประเมิน ตรวจช่องเปิดและพื้นหลัง แล้วตรวจไฟล์ที่ยอมรับแล้วในแอปที่บิลด์จริง
เพิ่มเติมจากบล็อก

ภาพ SVG ใน Flutter: รวมในแอป กำหนดขนาด และตรวจแอสเซ็ต
เพิ่มแอสเซ็ต SVG ใน Flutter ให้พาธ bundle ตรงกัน กำหนดมิติ widget และตรวจสีกับความหมายสำหรับการเข้าถึง แยกปัญหาโหลดจากงานภาพที่ไม่รองรับ

SVG ใน WPF: เลือกตัวเรนเดอร์หรือภาพวาด XAML
ใช้งาน SVG ใน WPF ด้วยตัวเรนเดอร์ DrawingImage เนทีฟ หรือ PNG ส่งออก ทำตามตัวอย่างไอคอนที่สร้างขึ้นและตรวจขอบเขต สี และ dependency