{"id":17040,"date":"2025-05-31T09:51:33","date_gmt":"2025-05-31T09:51:33","guid":{"rendered":"https:\/\/bestkora.com\/IosDeveloper\/?p=17040"},"modified":"2025-10-19T14:51:04","modified_gmt":"2025-10-19T14:51:04","slug":"%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8","status":"publish","type":"post","link":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/","title":{"rendered":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b.\u00a0"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/RecognizeTextGemini2_5.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"362\" height=\"742\" src=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/RecognizeTextGemini2_5.gif\" alt=\"\" class=\"wp-image-17066\" style=\"width:307px;height:auto\"\/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\"><code>Apple Pencil<\/code> \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b<code> iPad <\/code>\u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 <code>SwiftUI<\/code> \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a <code>Vision<\/code> \u043e\u0442 <code>Apple<\/code> \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 <code>PencilKit<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0418\u0442\u0430\u043a, <code>PencilKit<\/code> &#8212; \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, <code>Vision<\/code> &#8212; \u0434\u043b\u044f \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f, SwiftUI &#8212; \u0434\u043b\u044f UI.&nbsp;<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041a\u043e\u0434 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 <a href=\"https:\/\/github.com\/BestKora\/RecognozeTextGemini2_5\/blob\/main\/README.md\" title=\"\">GitHub<\/a>.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412\u043e\u043b\u0448\u0435\u0431\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0434\u0432\u0443\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 <code>Apple<\/code>:<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\"><strong>PencilKit (PKCanvasView)<\/strong>: \u044d\u0442\u043e\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u043a\u0443 \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0431\u0440\u043e\u0441\u043a\u0438 \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>Apple Pencil <\/code>\u0438\u043b\u0438 \u043f\u0430\u043b\u044c\u0446\u0430, \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u044f \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043a <code>PKDrawing<\/code> \u0434\u0430\u043d\u043d\u044b\u0435 \u2014 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>Strokes<\/code>.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><strong>Vision (VNRecognizeTextRequest)<\/strong>: \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0437\u0430\u0445\u0432\u0430\u0447\u0435\u043d, <code>Vision<\/code> \u0431\u0435\u0440\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u0431\u044f. <code>VNRecognizeTextRequest<\/code> \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442.<\/span><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u201c\u041c\u043e\u0441\u0442\u201d \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u041c\u0438\u0440\u0430\u043c\u0438: \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 PKCanvasView \u0432 SwiftUI<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>PKCanvasView<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c <code>UIKit<\/code>, \u0434\u043b\u044f \u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432 <code>SwiftUI<\/code> \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f <code>UIViewRepresentable<\/code>. \u042d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u0430\u043a \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e \u0432\u0430\u0436\u043d\u044b\u0439 \u201c\u043c\u043e\u0441\u0442\u201d, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f <code>SwiftUI<\/code> \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c <code>UIKit Views<\/code>. \u041a\u043b\u0430\u0441\u0441 <code>class<\/code> <code>Coordinator<\/code> \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0435\u0442 <code>UIViewRepresentable<\/code> \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u043e\u0432 \u0438\u0437 <code>PKCanvasView<\/code>, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, <code>canvasViewDrawingDidChange(_:),<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u043b \u0440\u0438\u0441\u0443\u043d\u043e\u043a <code>drawing<\/code>.<\/span><\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u041f\u0443\u0442\u044c \u043e\u0442 Stroke&nbsp; \u043a \u0441\u0442\u0440\u043e\u043a\u0435 String: \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441<\/strong><strong>.<\/strong><\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 <code>PencilKit<\/code>:<\/span>          <\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>PKCanvasView<\/code> \u0434\u043b\u044f \u0437\u0430\u0445\u0432\u0430\u0442\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 <code>drawings<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0440\u0430\u043d\u0434\u0430\u0448\u0430 <code>Pencil<\/code>.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <code>PKCanvasView<\/code> \u2014 \u044d\u0442\u043e <code>UIView<\/code>, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u0435\u0433\u043e \u0432 <code>UIViewRepresentable<\/code> \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 <code>SwiftUI<\/code>.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>PKToolPicker<\/code> \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f (\u043f\u0435\u0440\u043e, \u043b\u0430\u0441\u0442\u0438\u043a \u0438 \u0442. \u0434.).<\/span><\/li>\n<\/ul>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>Vision<\/code>:<\/span><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0438\u0441\u0443\u043d\u043e\u043a <code>drawing<\/code> \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f, \u043c\u044b \u0443\u0437\u043d\u0430\u0435\u043c \u043e\u0431 \u044d\u0442\u043e\u043c \u0432&nbsp; \u043c\u0435\u0442\u043e\u0434\u0435 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430 <code>canvasViewDrawingDidChange<\/code> \u0438 \u0442\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0440\u0438\u0441\u0443\u043d\u043e\u043a <code>PKDrawing<\/code>.&nbsp;<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c <code>PKDrawing<\/code> \u0432 <code>UIImage<\/code>.\u042d\u0442\u043e \u0440\u0430\u0441\u0442\u0440\u043e\u0432\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0435\u0433\u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u0435\u0442 \u043f\u0435\u0440\u0432\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u0410\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 (\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>UIScreen.main.scale<\/code>), \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u044b \u0432\u043e\u043a\u0440\u0443\u0433 \u0442\u0435\u043a\u0441\u0442\u0430 (\u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043e\u0431\u0440\u0435\u0437\u043a\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432) \u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u0441\u0442\u043d\u044b\u0439 \u0444\u043e\u043d \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>VNRecognizeTextRequest<\/code> \u0438\u0437 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 <code>Vision<\/code> \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c <code>SwiftUI<\/code> <code>View<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0436\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430.<\/span><\/li>\n<\/ul>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0417\u0430\u043f\u0440\u043e\u0441 <code>VNRecognizeTextRequest<\/code> \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438:<\/span><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\"><code>recognitionLevel: .accurate<\/code> \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435 \u0434\u043b\u044f \u043d\u044e\u0430\u043d\u0441\u043e\u0432 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code>recognizeLanguages:<\/code> \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e. \u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0445 \u043a\u043e\u0434\u043e\u0432 BCP 47 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, [&#171;en-US&#187;], [&#171;fr-FR&#187;], [&#171;ja-JP&#187;]) \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 <code>Vision<\/code> \u0441\u0443\u0437\u0438\u0442\u044c \u0444\u043e\u043a\u0443\u0441 \u0438 \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SwiftUI <code>Picker<\/code>, \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>VNRecognizeTextRequest.supportedRecognitionLanguages().<\/code><\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code>usesLanguageCorrection<\/code>: \u041e\u0431\u044b\u0447\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043b\u0438\u043d\u0433\u0432\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 Vision.<\/span><\/li>\n<\/ul>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0442\u0435\u043b\u044c <code>VNImageRequestHandler<\/code> \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f <code>CGImage<\/code>, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0437 (\u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0433\u043e) <code>UIImage<\/code>. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 <code>VNRecognizeTextRequest<\/code>. \u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 UI, \u044d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u200b\u200b\u0432 \u0444\u043e\u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a (<code>background thread<\/code>).<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432: \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0430 <code>request<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 <code>VNRecognizedTextObservation<\/code>. \u041a\u0430\u0436\u0434\u044b\u0439 \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a <code>topCandidates(1)<\/code> \u2014 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0439 \u0441\u0442\u0440\u043e\u043a.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 SwiftUI: \u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0437\u0430\u0442\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a <code>(main thread<\/code>) \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 SwiftUI, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 <code>TextEditor<\/code> \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u043c <code>Text<\/code>.<\/span><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u043e\u0434 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\"><strong>ContentView:<\/strong><\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);--cbp-line-highlight-color:rgba(134, 167, 228, 0.2);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import SwiftUI\nimport PencilKit\nimport Vision \/\/ Don't forget to import Vision\n\n\/\/ 1. SwiftUI View to host everything\nstruct ContentView: View {\n    @State private var drawing = PKDrawing()\n    @State private var recognizedText: String = \"Draw something and text will appear here.\"\n    \/\/ This will hold the tool picker instance\n    @State private var toolPicker = PKToolPicker()\n    var body: some View {\n        NavigationView {\n            VStack {\n                Text(\"Recognized Text:\")\n                    .font(.headline)\n                TextEditor(text: .constant(recognizedText)) \/\/ Use TextEditor for scrollable multi-line text\n                    .frame(height: 100)\n                    .border(Color.gray)\n                    .padding()\n               \n                Button(\"Clear Drawing\") {\n                    drawing = PKDrawing() \/\/ Reset the drawing\n                    recognizedText = \"Drawing cleared.\"\n                }\n                .padding()\n                Text(\"Canvas:\")\n                    .font(.headline)\n                DrawingView(drawing: $drawing, \n                            recognizedText: $recognizedText, \n                            toolPicker: $toolPicker)\n                    .frame(maxWidth: .infinity, maxHeight: .infinity)\n                    .border(Color.blue)\n                    .padding()\n            }\n         \/\/   .navigationTitle(\"Handwriting OCR\")\n            .navigationBarTitleDisplayMode(.inline)\n        }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">SwiftUI<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">PencilKit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">Vision<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Don&#39;t forget to import Vision<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ 1. SwiftUI View to host everything<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">struct<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">ContentView<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">View <\/span><span style=\"color: #ABB2BF\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> drawing = <\/span><span style=\"color: #61AFEF\">PKDrawing<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognizedText: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Draw something and text will appear here.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ This will hold the tool picker instance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> toolPicker = <\/span><span style=\"color: #61AFEF\">PKToolPicker<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> body: <\/span><span style=\"color: #C678DD\">some<\/span><span style=\"color: #ABB2BF\"> View {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">NavigationView<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #61AFEF\">VStack<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">Text<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Recognized Text:&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">font<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">headline<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">TextEditor<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">text<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #61AFEF\">constant<\/span><span style=\"color: #ABB2BF\">(recognizedText)) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Use TextEditor for scrollable multi-line text<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">frame<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">height<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">100<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">border<\/span><span style=\"color: #ABB2BF\">(Color.<\/span><span style=\"color: #E06C75\">gray<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">               <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">Button<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Clear Drawing&quot;<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    drawing = <\/span><span style=\"color: #61AFEF\">PKDrawing<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Reset the drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    recognizedText = <\/span><span style=\"color: #98C379\">&quot;Drawing cleared.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">Text<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Canvas:&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">font<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">headline<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">DrawingView<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">drawing<\/span><span style=\"color: #ABB2BF\">: $drawing, <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #ABB2BF\">                            <\/span><span style=\"color: #61AFEF\">recognizedText<\/span><span style=\"color: #ABB2BF\">: $recognizedText, <\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #ABB2BF\">                            <\/span><span style=\"color: #61AFEF\">toolPicker<\/span><span style=\"color: #ABB2BF\">: $toolPicker)<\/span><\/span>\n<span class=\"line cbp-line-highlight\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">frame<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">maxWidth<\/span><span style=\"color: #ABB2BF\">: .infinity, <\/span><span style=\"color: #61AFEF\">maxHeight<\/span><span style=\"color: #ABB2BF\">: .infinity)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">border<\/span><span style=\"color: #ABB2BF\">(Color.<\/span><span style=\"color: #E06C75\">blue<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">         <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/   .navigationTitle(&quot;Handwriting OCR&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            .<\/span><span style=\"color: #61AFEF\">navigationBarTitleDisplayMode<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">inline<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\"><code>@State var drawing:<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 <code>PKDrawing<\/code>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438 \u043e\u0447\u0438\u0449\u0430\u0442\u044c \u0440\u0438\u0441\u0443\u043d\u043e\u043a drawing.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code>@State var recognizedText:<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u0435\u043a\u0441\u0442, \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0439 <code>Vision<\/code>.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code>@State var toolPicker<\/code>: \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>PKToolPicker<\/code>. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0435\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code>DrawingView<\/code>: \u043d\u0430\u0448 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 <code>UIViewRepresentable <\/code>\u0434\u043b\u044f \u0445\u043e\u043b\u0441\u0442\u0430 (canvas).<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code>Button(\"Clear Drawing\"):<\/code> \u043e\u0447\u0438\u0449\u0430\u0435\u0442 <code>@State var drawing<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c (\u0447\u0435\u0440\u0435\u0437 <code>updateUIView)<\/code> \u043e\u0447\u0438\u0449\u0430\u0435\u0442 \u0445\u043e\u043b\u0441\u0442 (canvas).<\/span><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\"><strong>DrawingView (UIViewRepresentable):<\/strong><\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ 2. UIViewRepresentable for PKCanvasView\nstruct DrawingView: UIViewRepresentable {\n    @Binding var drawing: PKDrawing\n    @Binding var recognizedText: String\n    @Binding var toolPicker: PKToolPicker \/\/ Pass the tool picker\n\n    func makeUIView(context: Context) -> PKCanvasView {\n        let canvasView = PKCanvasView()\n        canvasView.drawing = drawing\n        canvasView.delegate = context.coordinator\n        canvasView.drawingPolicy = .anyInput \/\/ Or .pencilOnly for Apple Pencil only\n        canvasView.backgroundColor = .clear \/\/ Or any other color\n        canvasView.isOpaque = false\n       \n        \/\/ Show the tool picker\n        toolPicker.addObserver(canvasView) \/\/ Observe tool changes\n        toolPicker.setVisible(true, forFirstResponder: canvasView)\n        canvasView.becomeFirstResponder() \/\/ Important to make the canvas active for the tool picker\n        return canvasView\n    }\n   \n    func updateUIView(_ uiView: PKCanvasView, context: Context) {\n        \/\/ Update the drawing if it's changed from outside (e.g., by the \"Clear Drawing\" button)\n        if uiView.drawing != drawing {\n             uiView.drawing = drawing\n        }\n    }\n    func makeCoordinator() -> Coordinator {\n        Coordinator(self, recognizedText: $recognizedText)\n    }\n}   <\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ 2. UIViewRepresentable for PKCanvasView<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">struct<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">DrawingView<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">UIViewRepresentable <\/span><span style=\"color: #ABB2BF\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> drawing: PKDrawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognizedText: <\/span><span style=\"color: #E5C07B\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> toolPicker: PKToolPicker <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Pass the tool picker<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">makeUIView<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF; font-style: italic\">context<\/span><span style=\"color: #ABB2BF\">: Context) -&gt; PKCanvasView {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> canvasView = <\/span><span style=\"color: #61AFEF\">PKCanvasView<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\"> = drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">delegate<\/span><span style=\"color: #ABB2BF\"> = context.<\/span><span style=\"color: #E06C75\">coordinator<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">drawingPolicy<\/span><span style=\"color: #ABB2BF\"> = .<\/span><span style=\"color: #E06C75\">anyInput<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or .pencilOnly for Apple Pencil only<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">backgroundColor<\/span><span style=\"color: #ABB2BF\"> = .<\/span><span style=\"color: #E06C75\">clear<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or any other color<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">isOpaque<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Show the tool picker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        toolPicker.<\/span><span style=\"color: #61AFEF\">addObserver<\/span><span style=\"color: #ABB2BF\">(canvasView) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Observe tool changes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        toolPicker.<\/span><span style=\"color: #61AFEF\">setVisible<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66\">true<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">forFirstResponder<\/span><span style=\"color: #ABB2BF\">: canvasView)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #61AFEF\">becomeFirstResponder<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Important to make the canvas active for the tool picker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> canvasView<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">updateUIView<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">_<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">uiView<\/span><span style=\"color: #ABB2BF\">: PKCanvasView, <\/span><span style=\"color: #61AFEF; font-style: italic\">context<\/span><span style=\"color: #ABB2BF\">: Context) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Update the drawing if it&#39;s changed from outside (e.g., by the &quot;Clear Drawing&quot; button)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> uiView.drawing != drawing {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">             uiView.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\"> = drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">makeCoordinator<\/span><span style=\"color: #ABB2BF\">() -&gt; Coordinator {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">Coordinator<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">recognizedText<\/span><span style=\"color: #ABB2BF\">: $recognizedText)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}   <\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\"><code><strong>@Binding var drawing<\/strong><\/code>: \u0434\u0432\u0443\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u044f\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u043a <code>PKDrawing<\/code> \u0432 <code>ContentView<\/code>.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code><strong>@Binding var recognizedTex<\/strong>t:<\/code> \u043e\u0434\u043d\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u044f\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 (\u0445\u043e\u0442\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \u0434\u0432\u0443\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0439, \u0435\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e) \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 <code>ContentView<\/code>.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code><strong>@Binding var toolPicke<\/strong>r<\/code>: \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0438\u0437 <code>ContentView<\/code> \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code><strong>makeUIView<\/strong><\/code>:<\/span>\n<ul class=\"wp-block-list\">\n<li>    <span style=\"font-weight: 400;\">\u0421\u043e\u0437\u0434\u0430\u0435\u0442 <code>PKCanvasView<\/code>.<\/span>\n<ul class=\"wp-block-list\">\n<li>            <span style=\"font-weight: 400;\">\u041d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0438\u0441\u0443\u043d\u043e\u043a <code>drawing<\/code>.<\/span>\n<ul class=\"wp-block-list\">\n<li>            <span style=\"font-weight: 400;\">\u041d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430 <code>delegate<\/code> \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0443 <code>Coordinator<\/code>.<\/span>\n<ul class=\"wp-block-list\">\n<li>            <span style=\"font-weight: 400;\">\u0417\u0430\u0434\u0430\u0435\u0442 <code>drawingPolicy <\/code>(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>.anyInput<\/code> \u0434\u043b\u044f \u043f\u0430\u043b\u044c\u0446\u0430 \u0438 \u043a\u0430\u0440\u0430\u043d\u0434\u0430\u0448\u0430, <code>.pencilOnly<\/code> \u0434\u043b\u044f <code>Apple Pencil)<\/code>.<\/span>\n<ul class=\"wp-block-list\">\n<li>    <span style=\"font-weight: 400;\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430:<\/span>\n<ul class=\"wp-block-list\">\n<li>            <span style=\"font-weight: 400;\"><code>toolPicker.addObserver(canvasView)<\/code>: \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 <code>canvasView<\/code> \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430.<\/span>\n<ul class=\"wp-block-list\">\n<li>            <span style=\"font-weight: 400;\"><code>toolPicker.setVisible(true, forFirstResponder: canvasView)<\/code>: \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u044b\u0431\u043e\u0440 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430.<\/span>\n<ul class=\"wp-block-list\">\n<li>            <span style=\"font-weight: 400;\"><code>canvasView.becomeFirstResponder()<\/code>: \u0434\u0435\u043b\u0430\u0435\u0442 <code>canvasView<\/code> \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u043e\u0442\u0432\u0435\u0442\u0447\u0438\u043a\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u043e\u0440 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0437\u043d\u0430\u043b, \u0434\u043b\u044f \u043a\u0430\u043a\u043e\u0433\u043e <code>View<\/code> \u043e\u043d \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code><strong>updateUIView<\/strong>:<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>SwiftUI<\/code>, \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 View. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f uiView.drawing, \u0435\u0441\u043b\u0438 \u043d\u0430\u0448 \u0440\u0438\u0441\u0443\u043d\u043e\u043a @Binding drawing \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0438\u0437\u0432\u043d\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u00ab\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c\u00bb).&nbsp;<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><strong>makeCoordinator<\/strong>: \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 Coordinator.<\/span><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440 Coordinator \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(3 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class Coordinator: NSObject, PKCanvasViewDelegate {\n        var parent: DrawingView\n        @Binding var recognizedText: String\n        private var recognitionTask: DispatchWorkItem? \/\/ To debounce recognition\n\n      init(_ parent: DrawingView, recognizedText: Binding&lt;String>) {\n            self.parent = parent\n            self._recognizedText = recognizedText\n        }\n\n        func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {\n            \/\/ Update the parent's drawing binding\n            parent.drawing = canvasView.drawing\n    \/\/ Debounce recognition: Cancel previous task and schedule a new one\n            recognitionTask?.cancel()\n            let task = DispatchWorkItem { &#91;weak self&#93; in\n                self?.recognizeText(in: canvasView.drawing)\n            }\n            self.recognitionTask = task\n    \/\/ Perform recognition after a short delay to avoid excessive processing\n            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: task)\n        }\n\n        private func recognizeText(in currentDrawing: PKDrawing) {\n            \/\/ Ensure there's something to recognize\n            guard !currentDrawing.bounds.isEmpty else {\n                DispatchQueue.main.async {\n                    self.recognizedText = \"Canvas is empty.\"\n                }\n                return\n            }\n            \/\/-------------------\n            \/\/ 1. Get the current drawing from the canvas or state\n            \/\/ especially if they go near the edges of the tight `drawing.bounds`.\n            let imageRect = currentDrawing.bounds.insetBy(dx: -20, dy: -20)                  \n            let image = currentDrawing.image(from: imageRect, \n                                             scale: UIScreen.main.scale)\n            \/\/ 2. Create a Vision text recognition request\n            let request = VNRecognizeTextRequest { (request, error) in\n                if let error = error {\n            print(\"Error recognizing text: \\(error.localizedDescription)\")\n                    DispatchQueue.main.async {\n                self.recognizedText = \"Error: \\(error.localizedDescription)\"\n                    }\n                    return\n                }\n\n                guard let observations = \n                          request.results as? &#91;VNRecognizedTextObservation&#93;,     \n                                      !observations.isEmpty else {\n                    DispatchQueue.main.async {\n                        self.recognizedText = \"No text recognized.\"\n                    }\n                    return\n                }\n          let recognizedStrings = observations.compactMap { observation in\n                    \/\/ Return the string with the highest confidence.\n                    observation.topCandidates(1).first?.string\n          }\n                \n                DispatchQueue.main.async {\n                    self.recognizedText = \n                                   recognizedStrings.joined(separator: \"\\n\")\n                    if self.recognizedText.isEmpty {\n                         self.recognizedText = \n                         \"No text confidently recognized.\"\n                    }\n                }\n            }\n            \/\/ Optional: Configure the request\n            request.recognitionLevel = .accurate\/\/.fast\n            request.usesLanguageCorrection = true\n            request.recognitionLanguages = &#91;\"en-US\"&#93; \/\/ Specify languages \n            \/\/ Very important - set this to true for handwriting\n            if #available(iOS 16.0, *) {\n                request.automaticallyDetectsLanguage = false\n                request.revision = VNRecognizeTextRequestRevision3\n            }\n            \/\/ 3. Create a request handler and perform the request\n           guard let cgImage = image.cgImage else {\n                print(\"Failed to get CGImage from drawing.\")\n                DispatchQueue.main.async {\n                    self.recognizedText = \"Error processing drawing.\"\n                }\n                return\n            }\n            let handler = VNImageRequestHandler(cgImage: cgImage, \n                                                options: &#91;:&#93;)\n            DispatchQueue.global(qos: .userInitiated).async {\n                do {\n                    try handler.perform(&#91;request&#93;)\n                } catch {\n                    print(\n             \"Failed to perform recognition: \\(error.localizedDescription)\")\n                    DispatchQueue.main.async {\n                        self.recognizedText = \"Recognition failed.\"\n                    } \n                } \n            } \n        }   \n  }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">Coordinator<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">NSObject<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #E5C07B\">PKCanvasViewDelegate <\/span><span style=\"color: #ABB2BF\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> parent: DrawingView<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognizedText: <\/span><span style=\"color: #E5C07B\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognitionTask: DispatchWorkItem? <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ To debounce recognition<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #C678DD\">init<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">_<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">parent<\/span><span style=\"color: #ABB2BF\">: DrawingView, <\/span><span style=\"color: #61AFEF; font-style: italic\">recognizedText<\/span><span style=\"color: #ABB2BF\">: Binding&lt;<\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\">&gt;) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">parent<\/span><span style=\"color: #ABB2BF\"> = parent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">_recognizedText<\/span><span style=\"color: #ABB2BF\"> = recognizedText<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">canvasViewDrawingDidChange<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">_<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">canvasView<\/span><span style=\"color: #ABB2BF\">: PKCanvasView) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Update the parent&#39;s drawing binding<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            parent.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\"> = canvasView.<\/span><span style=\"color: #E06C75\">drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Debounce recognition: Cancel previous task and schedule a new one<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            recognitionTask?.<\/span><span style=\"color: #61AFEF\">cancel<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> task = <\/span><span style=\"color: #61AFEF\">DispatchWorkItem<\/span><span style=\"color: #ABB2BF\"> { &#91;<\/span><span style=\"color: #C678DD\">weak<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">&#93; <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">?.<\/span><span style=\"color: #61AFEF\">recognizeText<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\">: canvasView.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognitionTask<\/span><span style=\"color: #ABB2BF\"> = task<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Perform recognition after a short delay to avoid excessive processing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">asyncAfter<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">deadline<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #61AFEF\">now<\/span><span style=\"color: #ABB2BF\">() + <\/span><span style=\"color: #D19A66\">0.5<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">execute<\/span><span style=\"color: #ABB2BF\">: task)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">recognizeText<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">currentDrawing<\/span><span style=\"color: #ABB2BF\">: PKDrawing) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Ensure there&#39;s something to recognize<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> !currentDrawing.bounds.isEmpty <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Canvas is empty.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/-------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 1. Get the current drawing from the canvas or state<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ especially if they go near the edges of the tight `drawing.bounds`.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> imageRect = currentDrawing.<\/span><span style=\"color: #E06C75\">bounds<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">insetBy<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">dx<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">-20<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">dy<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">-20<\/span><span style=\"color: #ABB2BF\">)                  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> image = currentDrawing.image(<\/span><span style=\"color: #61AFEF\">from<\/span><span style=\"color: #ABB2BF\">: imageRect, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                             <\/span><span style=\"color: #61AFEF\">scale<\/span><span style=\"color: #ABB2BF\">: UIScreen.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">scale<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 2. Create a Vision text recognition request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> request = <\/span><span style=\"color: #61AFEF\">VNRecognizeTextRequest<\/span><span style=\"color: #ABB2BF\"> { (request, error) <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> error = error {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Error recognizing text: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Error: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> observations = <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          request.results as? &#91;VNRecognizedTextObservation&#93;,     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                      !observations.isEmpty <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;No text recognized.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> recognizedStrings = observations.<\/span><span style=\"color: #61AFEF\">compactMap<\/span><span style=\"color: #ABB2BF\"> { observation <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Return the string with the highest confidence.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    observation.<\/span><span style=\"color: #61AFEF\">topCandidates<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\">).first?.<\/span><span style=\"color: #E06C75\">string<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">          }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                   recognizedStrings.<\/span><span style=\"color: #56B6C2\">joined<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">separator<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #56B6C2\">\\n<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.recognizedText.isEmpty {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                         <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                         <\/span><span style=\"color: #98C379\">&quot;No text confidently recognized.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Optional: Configure the request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            request.<\/span><span style=\"color: #E06C75\">recognitionLevel<\/span><span style=\"color: #ABB2BF\"> = .<\/span><span style=\"color: #E06C75\">accurate<\/span><span style=\"color: #7F848E; font-style: italic\">\/\/.fast<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            request.<\/span><span style=\"color: #E06C75\">usesLanguageCorrection<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            request.<\/span><span style=\"color: #E06C75\">recognitionLanguages<\/span><span style=\"color: #ABB2BF\"> = &#91;<\/span><span style=\"color: #98C379\">&quot;en-US&quot;<\/span><span style=\"color: #ABB2BF\">&#93; <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Specify languages <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Very important - set this to true for handwriting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">#available<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #C678DD\">iOS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">16.0<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #C678DD\">*<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                request.<\/span><span style=\"color: #E06C75\">automaticallyDetectsLanguage<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                request.<\/span><span style=\"color: #E06C75\">revision<\/span><span style=\"color: #ABB2BF\"> = VNRecognizeTextRequestRevision3<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 3. Create a request handler and perform the request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> cgImage = image.cgImage <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Failed to get CGImage from drawing.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Error processing drawing.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> handler = <\/span><span style=\"color: #61AFEF\">VNImageRequestHandler<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">cgImage<\/span><span style=\"color: #ABB2BF\">: cgImage, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                                <\/span><span style=\"color: #61AFEF\">options<\/span><span style=\"color: #ABB2BF\">: &#91;<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\">&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            DispatchQueue.<\/span><span style=\"color: #61AFEF\">global<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">qos<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #E06C75\">userInitiated<\/span><span style=\"color: #ABB2BF\">).<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">do<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">try<\/span><span style=\"color: #ABB2BF\"> handler.<\/span><span style=\"color: #61AFEF\">perform<\/span><span style=\"color: #ABB2BF\">(&#91;request&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                } <\/span><span style=\"color: #C678DD\">catch<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">             <\/span><span style=\"color: #98C379\">&quot;Failed to perform recognition: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Recognition failed.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    } <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                } <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            } <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">PKCanvasViewDelegate: \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 drawing.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">parent: \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 DrawingView.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">@Binding var recognizedText: \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f SwiftUI.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">recognizedTask: DispatchWorkItem, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0440\u0435\u0431\u0435\u0437\u0433\u0430. \u042d\u0442\u043e \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0447\u0440\u0435\u0437\u043c\u0435\u0440\u043d\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430, \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0438\u0441\u0443\u0435\u0442 drawing. \u041e\u043d \u0436\u0434\u0435\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0439 \u043f\u0430\u0443\u0437\u044b (\u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 0,5 \u0441\u0435\u043a\u0443\u043d\u0434\u044b) \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><code><strong>canvasViewDrawingDidChange(_:):<\/strong><\/code><\/span>\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u042d\u0442\u043e \u0432\u0430\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 drawing \u043d\u0430 PKCanvasView.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041e\u043d \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 parent.drawing, \u0447\u0442\u043e\u0431\u044b @State drawing \u0432 ContentView \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041e\u043d \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442 (cancels) \u043b\u044e\u0431\u0443\u044e \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u043d\u043e\u0432\u0443\u044e.<\/span><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>recognizedText(in:):\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435: currentDrawing.image(from:scale:) \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 PKDrawing \u0432 UIImage. imageRect \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c drawing.bounds, \u0447\u0442\u043e\u0431\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u0437\u0430\u0445\u0432\u0430\u0442 strokes \u043e\u043a\u043e\u043b\u043e \u043a\u0440\u0430\u044f.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0417\u0430\u043f\u0440\u043e\u0441 Vision:<\/span>\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">VNRecognizeTextRequest \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d. \u0415\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 [VNRecognizedTextObservation].<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041a\u0430\u0436\u0434\u044b\u0439 VNRecognizedTextObservation \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0430. topCandidates(1).first?.string \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435.<\/span><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0430 Request Handler:<\/span>\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">VNImageRequestHandler \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e cgImage \u0440\u0438\u0441\u0443\u043d\u043a\u0430 drawing.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">handler.perform([request]) \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 (DispatchQueue.global(qos: .userInitiated).async), \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b RecognizeTextGemini25 \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u043a\u0435:<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0415\u0441\u043b\u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0446\u0432\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043e\u0442 \u0447\u0435\u0440\u043d\u043e\u0433\u043e, \u0442\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e:<\/span><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.19.02.png\"><img loading=\"lazy\" decoding=\"async\" width=\"523\" height=\"1024\" src=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.19.02-523x1024.png\" alt=\"\" class=\"wp-image-17053\" srcset=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.19.02-523x1024.png 523w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.19.02-153x300.png 153w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.19.02.png 690w\" sizes=\"auto, (max-width: 523px) 100vw, 523px\" \/><\/a><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screen-Recording-2025-06-02-at-19.39.45-1.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"360\" height=\"748\" src=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screen-Recording-2025-06-02-at-19.39.45-1.gif\" alt=\"\" class=\"wp-image-17055\" style=\"width:269px;height:auto\"\/><\/a><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041e\u0434\u043d\u0430\u043a\u043e \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u043d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442\u0441\u044f, \u0445\u043e\u0442\u044f \u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0446\u0432\u0435\u0442\u043e\u043c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u044b \u043f\u043e\u043f\u0430\u0434\u0435\u0442\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXcDXnI6A-NN_6M6ouNIHocg_Ntg_vGEu_hmQUCKcwmCkSXQMX1ogM2JIpYXk6BmCASs4WjFEF6sj7Nh4JGTNG0IApuskAhBFUkP9Wdc0sSoOeLEv5gHLCuaWSbwQTfvwYjcory08A?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 (\u0434\u0430\u0436\u0435 \u0442\u0435\u043c\u043d\u044b\u0439) \u0446\u0432\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXet1sztmMm__lLDYY-eYGodH2Xr8EKuw7wUOILZn6Ld-eMwN6MwoUXEBvynIgUpEVMOVB53keRdQtfuIDumSnXVC4ZqN3oZh1v82BKIu6yRzO_pi7nIFARb-3Al_2ApKWz2Kek3rw?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041c\u0430\u0440\u043a\u0435\u0440 \u0442\u043e\u0436\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u043e:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXcsPusJMCO37V80oV9JKg2N9t1aszsFi6q5mVGCbDSDTQxD2IouZOmEiUZNiW0s3E66EZFLFujTHzHOYD_4mjGv5sf3ZUh9EwSF7ywCEZFAheS6Rb2QRCPwlS0uxJPqBb62kSHJSw?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0411\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u0442\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0447\u0435\u0440\u043d\u044b\u0439 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043b\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u044b <strong>\u0441\u0442\u0440\u043e\u0433\u043e \u0447\u0435\u0440\u043d\u043e\u0433\u043e <\/strong>\u0446\u0432\u0435\u0442\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0430<strong> \u201c\u043f\u043e\u0447\u0442\u0438\u201d \u0447\u0435\u0440\u043d\u044b\u0439<\/strong>.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u0417\u0430\u043c\u0435\u043d\u0430 \u0441\u0442\u0440\u043e\u0433\u043e \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0430 \u201c\u043f\u043e\u0447\u0442\u0438\u201d \u0447\u0435\u0440\u043d\u044b\u0439.<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041f\u043e\u043f\u0440\u043e\u0441\u0438\u043c Gemini 2.5 Pro \u043f\u043e\u043c\u043e\u0447\u044c \u043d\u0430\u043c&nbsp; \u0441 \u044d\u0442\u0438\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c.<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXe5qquabZYAzINGsaI9pFyGtiQkJfvdUN8JxTmRg4uwD4ZLU-M4-f2cKa7F3vs2rb-KYDJCF24fodwOp8SRGOTkQD6-SFeZZYz8DB_7yvS3y14rvl8-1jbE46qrMz4lzdoGrCUS?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.50.41.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"148\" src=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.50.41-1024x148.png\" alt=\"\" class=\"wp-image-17057\" srcset=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.50.41-1024x148.png 1024w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.50.41-300x43.png 300w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.50.41-768x111.png 768w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.50.41-500x72.png 500w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-02-at-19.50.41.png 1382w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0425\u043e\u0440\u043e\u0448\u043e, \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0442\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e strokes \u0432 PKDrawing, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0435\u0440\u043d\u044b\u0439 \u043b\u0438 \u0443 \u043d\u0438\u0445 \u0446\u0432\u0435\u0442 \u0447\u0435\u0440\u043d\u0438\u043b (\u0438\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u0431\u043b\u0438\u0437\u043a\u0438\u0439 \u043a \u0447\u0435\u0440\u043d\u043e\u043c\u0443), \u0438 \u0435\u0441\u043b\u0438 \u0434\u0430, \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 <strong>\u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u0435\u0435 \u0438\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u044b\u0439 \u0447\u0435\u0440\u043d\u044b\u0439 <\/strong>(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0435\u043c\u043d\u043e-\u0441\u0435\u0440\u044b\u0439). \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0435\u0441\u043b\u0438 \u00ab\u0447\u0438\u0441\u0442\u044b\u0439 \u0447\u0435\u0440\u043d\u044b\u0439\u00bb \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439. \u0412\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u0412\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 PKDrawing \u0441 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u043c\u0438 Strokes, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 PKStroke \u0438 PKInk \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b.<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u0430 \u00ab\u0431\u043b\u0438\u0437\u043a\u043e\u0433\u043e \u043a \u0447\u0435\u0440\u043d\u043e\u043c\u0443\u00bb <\/strong><strong>isEssentiallyBlack(tolerance:)<\/strong><strong>:<\/strong><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 UIColor \u00ab\u0447\u0435\u0440\u043d\u044b\u043c\u00bb. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0446\u0432\u0435\u0442\u0430 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u0438, \u0442\u043e\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0447\u0435\u0440\u043d\u044b\u0439 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0447\u043d\u043e UIColor(red: 0, green: 0, blue: 0, alpha: 1).<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>extension UIColor {\n        \/\/ Check if this color is essentially black\n        func isEssentiallyBlack(tolerance: CGFloat = 0.05) -> Bool {\n            var r: CGFloat = 0\n            var g: CGFloat = 0\n            var b: CGFloat = 0\n            var a: CGFloat = 0\n            \n           \/\/ Convert to sRGB to get consistent components for black\n            guard let srgbColor = self.convertToSRGB() else {\n                \/\/ Fallback or handle error if conversion fails\n                \/\/ For black, if conversion fails, it's unlikely to be black anyway\n                return false\n            }\n            \n            srgbColor.getRed(&amp;r, green: &amp;g, blue: &amp;b, alpha: &amp;a)\n            return r &lt;= tolerance &amp;&amp; g &lt;= tolerance &amp;&amp; b &lt;= tolerance \/*&amp;&amp; a >= (1.0 - tolerance)*\/\n        }\n\n        \/\/ Convert UIColor to sRGB color space\n        func convertToSRGB() -> UIColor? {\n            \/\/ If already sRGB, no need to convert (though converting again is safe)\n            \/\/ Note: Comparing CGColor.colorSpace is more robust than string matching name\n            if self.cgColor.colorSpace?.name == CGColorSpace.sRGB {\n                return self\n            }\n            var r: CGFloat = 0\n            var g: CGFloat = 0\n            var b: CGFloat = 0\n            var a: CGFloat = 0\n            \n            \/\/ GetRed can convert simple color spaces (like gray) to a compatible RGB\n            if self.getRed(&amp;r, green: &amp;g, blue: &amp;b, alpha: &amp;a) {\n                return UIColor(red: r, green: g, blue: b, alpha: a) \/\/ This will be in sRGB by default\n            } else {\n                \/\/ More robust conversion using a graphics context (handles more color spaces)\n                let newColorSpace = CGColorSpace(name: CGColorSpace.sRGB)!\n                let cgColor = self.cgColor\n                guard let convertedCGColor = cgColor.converted(to: newColorSpace, intent: .defaultIntent, options: nil) else {\n                    print(\"Warning: Could not convert color \\(self) to sRGB.\")\n                    return nil \/\/ Or return self if conversion fails, depending on desired behavior\n                }\n                return UIColor(cgColor: convertedCGColor)\n            }\n        }\n    }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">extension<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">UIColor<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Check if this color is essentially black<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF; font-style: italic\">tolerance<\/span><span style=\"color: #ABB2BF\">: CGFloat <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0.05<\/span><span style=\"color: #ABB2BF\">) -&gt; <\/span><span style=\"color: #E5C07B\">Bool<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> r: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> g: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> b: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> a: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Convert to sRGB to get consistent components for black<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> srgbColor = <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">convertToSRGB<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Fallback or handle error if conversion fails<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ For black, if conversion fails, it&#39;s unlikely to be black anyway<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            srgbColor.<\/span><span style=\"color: #61AFEF\">getRed<\/span><span style=\"color: #ABB2BF\">(&amp;r, <\/span><span style=\"color: #61AFEF\">green<\/span><span style=\"color: #ABB2BF\">: &amp;g, <\/span><span style=\"color: #61AFEF\">blue<\/span><span style=\"color: #ABB2BF\">: &amp;b, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: &amp;a)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> r &lt;= tolerance &amp;&amp; g &lt;= tolerance &amp;&amp; b &lt;= tolerance <\/span><span style=\"color: #7F848E; font-style: italic\">\/*&amp;&amp; a &gt;= (1.0 - tolerance)*\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Convert UIColor to sRGB color space<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">convertToSRGB<\/span><span style=\"color: #ABB2BF\">() -&gt; UIColor? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ If already sRGB, no need to convert (though converting again is safe)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Note: Comparing CGColor.colorSpace is more robust than string matching name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.cgColor.colorSpace?.name == CGColorSpace.sRGB {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> r: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> g: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> b: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> a: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ GetRed can convert simple color spaces (like gray) to a compatible RGB<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">getRed<\/span><span style=\"color: #ABB2BF\">(&amp;r, <\/span><span style=\"color: #61AFEF\">green<\/span><span style=\"color: #ABB2BF\">: &amp;g, <\/span><span style=\"color: #61AFEF\">blue<\/span><span style=\"color: #ABB2BF\">: &amp;b, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: &amp;a) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">UIColor<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">red<\/span><span style=\"color: #ABB2BF\">: r, <\/span><span style=\"color: #61AFEF\">green<\/span><span style=\"color: #ABB2BF\">: g, <\/span><span style=\"color: #61AFEF\">blue<\/span><span style=\"color: #ABB2BF\">: b, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: a) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ This will be in sRGB by default<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ More robust conversion using a graphics context (handles more color spaces)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newColorSpace = <\/span><span style=\"color: #61AFEF\">CGColorSpace<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">name<\/span><span style=\"color: #ABB2BF\">: CGColorSpace.<\/span><span style=\"color: #E06C75\">sRGB<\/span><span style=\"color: #ABB2BF\">)!<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> cgColor = <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">cgColor<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> convertedCGColor = cgColor.<\/span><span style=\"color: #61AFEF\">converted<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\">: newColorSpace, <\/span><span style=\"color: #61AFEF\">intent<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #E06C75\">defaultIntent<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">options<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">nil<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Warning: Could not convert color <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> to sRGB.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">nil<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or return self if conversion fails, depending on desired behavior<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">UIColor<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">cgColor<\/span><span style=\"color: #ABB2BF\">: convertedCGColor)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f extension UIColor \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b RGB. \u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u043e\u043d\u0438 \u043d\u0438\u0436\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 0,05, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043c\u0435\u043d\u0435\u0435 5% \u0438\u043d\u0442\u0435\u043d\u0441\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043a\u0440\u0430\u0441\u043d\u043e\u0433\u043e, \u0437\u0435\u043b\u0435\u043d\u043e\u0433\u043e \u0438 \u0441\u0438\u043d\u0435\u0433\u043e), \u0442\u043e \u043e\u043d \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u043d\u044b\u043c. \u041d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c alpha \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u0441 \u043b\u044e\u0431\u043e\u0439 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u043d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u043e\u0434\u043b\u0435\u0436\u0438\u0442 \u0437\u0430\u043c\u0435\u043d\u0435. \u042d\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0438, \u043a\u043e\u0433\u0434\u0430 \u0447\u0435\u0440\u043d\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c UIColor(red: 0,01, green: 0,02, blue: 0,01, alpha: 1,0) \u0438\u043b\u0438&nbsp; UIColor(red: 0,01, green: 0,02, blue: 0,01, alpha: 0,27).<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">2. <strong>&nbsp;newDarkGrayColor<\/strong>: \u042d\u0442\u043e \u0446\u0432\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0447\u0435\u0440\u043d\u044b\u0439. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0435\u0433\u043e.<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ Define your new \"not so black\" color\nlet newDarkGrayColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1.0) \/\/ Example: Dark Gray\n\/\/ Or: UIColor.darkGray<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ Define your new &quot;not so black&quot; color<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newDarkGrayColor = <\/span><span style=\"color: #61AFEF\">UIColor<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">red<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.2<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">green<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.2<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">blue<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.2<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">1.0<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Example: Dark Gray<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ Or: UIColor.darkGray<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">3. \u0424\u0443\u043d\u043a\u0446\u0438\u044f<strong> modifyBlackStrokes<\/strong> \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u0430 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u043d\u044b\u0445 strokes \u043d\u0430 \u00ab\u0431\u043b\u0438\u0437\u043a\u0438\u0439 \u043a \u0447\u0435\u0440\u043d\u043e\u043c\u0443\u00bb \u0446\u0432\u0435\u0442<strong>:<\/strong><\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>func modifyBlackStrokes(in drawing: PKDrawing,\n                         to newColor: UIColor,\n                         blacknessTolerance: CGFloat = 0.05) -> PKDrawing {\n   var modifiedStrokes: &#91;PKStroke&#93; = []\n   for originalStroke in drawing.strokes {\n      \/\/ Check if the original stroke's ink color is essentially black\n     if originalStroke.ink.color.isEssentiallyBlack(tolerance: blacknessTolerance) {\n      \/\/ Create a new ink with the new color, keeping other ink properties\n            let newInk = PKInk(originalStroke.ink.inkType, color: newColor)\n                    \n      \/\/ Create a new stroke with the new ink but the same path and transform\n            let newStroke = PKStroke(ink: newInk, path: originalStroke.path, \n                                     transform: originalStroke.transform, \n                                     mask: originalStroke.mask)\n             modifiedStrokes.append(newStroke)\n       } else {\n                    \/\/ If the stroke is not black, keep it as is\n               modifiedStrokes.append(originalStroke)\n        }\n    }\n            return PKDrawing(strokes: modifiedStrokes)\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">modifyBlackStrokes<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">drawing<\/span><span style=\"color: #ABB2BF\">: PKDrawing,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                         <\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">newColor<\/span><span style=\"color: #ABB2BF\">: UIColor,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                         <\/span><span style=\"color: #61AFEF; font-style: italic\">blacknessTolerance<\/span><span style=\"color: #ABB2BF\">: CGFloat <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0.05<\/span><span style=\"color: #ABB2BF\">) -&gt; PKDrawing {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> modifiedStrokes: &#91;PKStroke&#93; = []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #C678DD\">for<\/span><span style=\"color: #ABB2BF\"> originalStroke <\/span><span style=\"color: #C678DD\">in<\/span><span style=\"color: #ABB2BF\"> drawing.strokes {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Check if the original stroke&#39;s ink color is essentially black<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> originalStroke.ink.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: blacknessTolerance) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Create a new ink with the new color, keeping other ink properties<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newInk = <\/span><span style=\"color: #61AFEF\">PKInk<\/span><span style=\"color: #ABB2BF\">(originalStroke.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">inkType<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">color<\/span><span style=\"color: #ABB2BF\">: newColor)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Create a new stroke with the new ink but the same path and transform<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newStroke = <\/span><span style=\"color: #61AFEF\">PKStroke<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">ink<\/span><span style=\"color: #ABB2BF\">: newInk, <\/span><span style=\"color: #61AFEF\">path<\/span><span style=\"color: #ABB2BF\">: originalStroke.<\/span><span style=\"color: #E06C75\">path<\/span><span style=\"color: #ABB2BF\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                     <\/span><span style=\"color: #61AFEF\">transform<\/span><span style=\"color: #ABB2BF\">: originalStroke.<\/span><span style=\"color: #E06C75\">transform<\/span><span style=\"color: #ABB2BF\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                     <\/span><span style=\"color: #61AFEF\">mask<\/span><span style=\"color: #ABB2BF\">: originalStroke.<\/span><span style=\"color: #E06C75\">mask<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">             modifiedStrokes.<\/span><span style=\"color: #56B6C2\">append<\/span><span style=\"color: #ABB2BF\">(newStroke)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">       } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ If the stroke is not black, keep it as is<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">               modifiedStrokes.<\/span><span style=\"color: #56B6C2\">append<\/span><span style=\"color: #ABB2BF\">(originalStroke)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">PKDrawing<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">strokes<\/span><span style=\"color: #ABB2BF\">: modifiedStrokes)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 PKStroke \u0432 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 drawing, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e stroke \u043e\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0446\u0432\u0435\u0442 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e originalStroke.ink.color \u043d\u0430 \u0447\u0438\u0441\u0442\u043e \u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e isEssentiallyBlack.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0415\u0441\u043b\u0438 \u0446\u0432\u0435\u0442 stroke &#8212; \u0447\u0435\u0440\u043d\u044b\u0439:<\/span>\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u041e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 PKInk. \u0412\u0430\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c originalStroke.ink.inkType \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 \u0447\u0435\u0440\u043d\u0438\u043b (\u0440\u0443\u0447\u043a\u0430, \u043a\u0430\u0440\u0430\u043d\u0434\u0430\u0448, \u043c\u0430\u0440\u043a\u0435\u0440). \u0418\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0446\u0432\u0435\u0442.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0417\u0430\u0442\u0435\u043c \u043e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 PKStroke \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c newInk, \u043d\u043e \u043a\u043e\u043f\u0438\u0440\u0443\u044f \u043f\u0443\u0442\u044c path, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 transform \u0438 \u043c\u0430\u0441\u043a\u0443 mask \u0438\u0437 originalStroke. \u042d\u0442\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0444\u043e\u0440\u043c\u0430 \u0438 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 strokes&nbsp; \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u043c\u0438, a \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u0440 \u0446\u0432\u0435\u0442 \u0441 \u0447\u0438\u0441\u0442\u043e \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u043d\u0430 \u201c\u0431\u043b\u0438\u0437\u043a\u0438\u0439 \u043a \u0447\u0435\u0440\u043d\u043e\u043c\u0443\u201d newColor.<\/span><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0415\u0441\u043b\u0438 \u0446\u0432\u0435\u0442 stroke \u043d\u0435 \u0447\u0435\u0440\u043d\u044b\u0439, stroke \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 modifiedStrokes \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 PKDrawing, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 modifiedStrokes.<\/span><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">4. <span style=\"font-weight: 400;\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 recognizedText(in:):<\/span><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0412\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 modifyBlackStrokes \u0441 \u0432\u0430\u0448\u0438\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u043c drawing \u0438 \u0436\u0435\u043b\u0430\u0435\u043c\u044b\u043c \u043d\u043e\u0432\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u043d\u044b\u0439 modifiedDrawing \u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f OCR) \u0438\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 PKCanvasView.drawing, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0432\u0438\u0434\u0435\u043b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0445\u043e\u043b\u0441\u0442\u0435 (canvas).<\/span><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u042d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u043b\u0430\u0435\u0442\u0435 \u043d\u0435\u0440\u0430\u0437\u0440\u0443\u0448\u0430\u044e\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f&nbsp; drawing (\u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u043d\u043e\u0432\u044b\u0439) \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0435 \u0432\u0441\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b strokes, \u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0446\u0432\u0435\u0442\u0430 \u0442\u0435\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u043b\u0438 \u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412\u043e\u0442 \u043a\u0430\u043a \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f \u043a\u043e\u0434 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 recognizedText(in:):<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>func recognizeHandwriting() {\n        isRecognizing = true\n   \n        \/\/------\n        \/\/ 1. Get the current drawing from the canvas or state\n        let originalDrawing = canvasView.drawing \/\/ Or self.currentDrawing\n        \/\/ 2. Define the target \"not so black\" color\n        let slightlyLighterBlack = UIColor(white: 0.15, alpha: 1.0) \/\/ A very dark gray\n        \/\/ 3. Modify the drawing\n        let modifiedDrawing = modifyBlackStrokes(in: originalDrawing,\n                                                 to: slightlyLighterBlack,\n                                                 blacknessTolerance: 0.1)\n        \/\/-------------PRINT-----\n        let originalBlackStrokes = originalDrawing.strokes.filter { \n                    $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n        let newBlackStrokes = modifiedDrawing.strokes.filter { \n                    $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n        \n        print(\"Original drawing had \\(originalBlackStrokes) black strokes.\")\n        print(\"Modified drawing has \\(newBlackStrokes) black strokes (should be 0 if all were changed).\")\n        let newColorStrokes = modifiedDrawing.strokes.filter { \n                    $0.ink.color.isEqual(slightlyLighterBlack)}.count\n  print(\"Modified drawing has \\(newColorStrokes) strokes with the new color.\")\n        \/\/------------\n       \n       let image = modifiedDrawing.image(from: \n                            modifiedDrawing.bounds.insetBy(dx: -20, dy: -20),\n                            scale: UIScreen.main.scale)\n           \n        \/\/ Create a request handler\n        guard let cgImage = image.cgImage else {\n            print(\"Could not get CGImage from UIImage\")\n            isRecognizing = false\n            return\n        }\n        \/\/ Important: Create the request with the recognition level set to accurate\n        let request = VNRecognizeTextRequest { (request, error) in\n            if let error = error {\n                print(\"Error: \\(error)\")\n                isRecognizing = false\n                return\n            }\n            \n            guard let observations = request.results as?    \n                                 &#91;VNRecognizedTextObservation&#93; else {\n                print(\"No text observations\")\n                isRecognizing = false\n                return\n            }\n            \n            \/\/ Process the recognized text\n            let recognizedStrings = observations.compactMap { observation in\n                observation.topCandidates(1).first?.string\n            }\n            \n            DispatchQueue.main.async {\n                self.recognizedText = recognizedStrings.joined(separator: \" \")\n                self.isRecognizing = false\n            }\n        }\n        \n        \/\/ THIS IS THE KEY: Set recognition to handwriting mode\n        request.recognitionLevel =  .accurate\/\/.fast.\n        request.recognitionLanguages = &#91;\"en-US\"&#93;\n        request.usesLanguageCorrection = true\n        request.customWords = &#91;\"o3Draw\"&#93; \/\/ Add custom words that might appear in your app\n        \n        \/\/ Very important - set this to true for handwriting\n        if #available(iOS 16.0, *) {\n            request.automaticallyDetectsLanguage = false\n            request.revision = VNRecognizeTextRequestRevision3\n        }\n        \n        DispatchQueue.global(qos: .userInitiated).async {\n            do {\n                let requestHandler = VNImageRequestHandler(cgImage: cgImage, \n                                                           options: &#91;:&#93;)\n                try requestHandler.perform(&#91;request&#93;)\n            } catch {\n                print(\n             \"Failed to perform recognition: \\(error.localizedDescription)\")\n                DispatchQueue.main.async {\n                    self.recognizedText = \"Recognition failed.\"\n                }\n            }\n        }\n    }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">recognizeHandwriting<\/span><span style=\"color: #ABB2BF\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        isRecognizing = <\/span><span style=\"color: #D19A66\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 1. Get the current drawing from the canvas or state<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> originalDrawing = canvasView.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or self.currentDrawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 2. Define the target &quot;not so black&quot; color<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> slightlyLighterBlack = <\/span><span style=\"color: #61AFEF\">UIColor<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">white<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.15<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">1.0<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ A very dark gray<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 3. Modify the drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> modifiedDrawing = <\/span><span style=\"color: #61AFEF\">modifyBlackStrokes<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\">: originalDrawing,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                                 <\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\">: slightlyLighterBlack,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                                 <\/span><span style=\"color: #61AFEF\">blacknessTolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/-------------PRINT-----<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> originalBlackStrokes = originalDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newBlackStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Original drawing had <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">originalBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes (should be 0 if all were changed).&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newColorStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #56B6C2\">isEqual<\/span><span style=\"color: #ABB2BF\">(slightlyLighterBlack)}.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newColorStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> strokes with the new color.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> image = modifiedDrawing.image(<\/span><span style=\"color: #61AFEF\">from<\/span><span style=\"color: #ABB2BF\">: <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                            modifiedDrawing.<\/span><span style=\"color: #E06C75\">bounds<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">insetBy<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">dx<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">-20<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">dy<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">-20<\/span><span style=\"color: #ABB2BF\">),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                            <\/span><span style=\"color: #61AFEF\">scale<\/span><span style=\"color: #ABB2BF\">: UIScreen.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">scale<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Create a request handler<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> cgImage = image.cgImage <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Could not get CGImage from UIImage&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            isRecognizing = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Important: Create the request with the recognition level set to accurate<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> request = <\/span><span style=\"color: #61AFEF\">VNRecognizeTextRequest<\/span><span style=\"color: #ABB2BF\"> { (request, error) <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> error = error {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Error: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                isRecognizing = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> observations = request.results as?    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                 &#91;VNRecognizedTextObservation&#93; <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;No text observations&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                isRecognizing = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Process the recognized text<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> recognizedStrings = observations.<\/span><span style=\"color: #61AFEF\">compactMap<\/span><span style=\"color: #ABB2BF\"> { observation <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                observation.<\/span><span style=\"color: #61AFEF\">topCandidates<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\">).first?.<\/span><span style=\"color: #E06C75\">string<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = recognizedStrings.<\/span><span style=\"color: #56B6C2\">joined<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">separator<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #98C379\">&quot; &quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">isRecognizing<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ THIS IS THE KEY: Set recognition to handwriting mode<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        request.<\/span><span style=\"color: #E06C75\">recognitionLevel<\/span><span style=\"color: #ABB2BF\"> =  .<\/span><span style=\"color: #E06C75\">accurate<\/span><span style=\"color: #7F848E; font-style: italic\">\/\/.fast.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        request.<\/span><span style=\"color: #E06C75\">recognitionLanguages<\/span><span style=\"color: #ABB2BF\"> = &#91;<\/span><span style=\"color: #98C379\">&quot;en-US&quot;<\/span><span style=\"color: #ABB2BF\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        request.<\/span><span style=\"color: #E06C75\">usesLanguageCorrection<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        request.<\/span><span style=\"color: #E06C75\">customWords<\/span><span style=\"color: #ABB2BF\"> = &#91;<\/span><span style=\"color: #98C379\">&quot;o3Draw&quot;<\/span><span style=\"color: #ABB2BF\">&#93; <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Add custom words that might appear in your app<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Very important - set this to true for handwriting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">#available<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #C678DD\">iOS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">16.0<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #C678DD\">*<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            request.<\/span><span style=\"color: #E06C75\">automaticallyDetectsLanguage<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            request.<\/span><span style=\"color: #E06C75\">revision<\/span><span style=\"color: #ABB2BF\"> = VNRecognizeTextRequestRevision3<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        DispatchQueue.<\/span><span style=\"color: #61AFEF\">global<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">qos<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #E06C75\">userInitiated<\/span><span style=\"color: #ABB2BF\">).<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">do<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> requestHandler = <\/span><span style=\"color: #61AFEF\">VNImageRequestHandler<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">cgImage<\/span><span style=\"color: #ABB2BF\">: cgImage, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                                           <\/span><span style=\"color: #61AFEF\">options<\/span><span style=\"color: #ABB2BF\">: &#91;<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\">&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">try<\/span><span style=\"color: #ABB2BF\"> requestHandler.<\/span><span style=\"color: #61AFEF\">perform<\/span><span style=\"color: #ABB2BF\">(&#91;request&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            } <\/span><span style=\"color: #C678DD\">catch<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">             <\/span><span style=\"color: #98C379\">&quot;Failed to perform recognition: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Recognition failed.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430\u0448\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u0446\u0432\u0435\u0442\u0430\u043c\u0438 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 &#8212;- PRINT &#8212;- \u0441 \u043f\u0435\u0447\u0430\u0442\u044c\u044e \u0442\u043e\u0433\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e strokes \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c drawing,\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c strokes \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c drawing \u0438 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e strokes \u0441 \u043d\u043e\u0432\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c drawing:<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/-------------PRINT-----\n            let originalBlackStrokes = currentDrawing.strokes.filter { \n                    $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n            let newBlackStrokes = modifiedDrawing.strokes.filter { \n                    $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n            let newColorStrokes = modifiedDrawing.strokes.filter {\n              $0.ink.color.isVisuallyEqual(to: slightlyLighterBlack)}.count\n            \n            print(\n            \"Original drawing had \\(originalBlackStrokes) black strokes.\")\n            print(\"Modified drawing has \\(newBlackStrokes) black strokes (should be 0 if all were changed).\")\n            print(\n        \"Modified drawing has \\(newColorStrokes) strokes with the new color.\")\n\/\/------------<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/-------------PRINT-----<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> originalBlackStrokes = currentDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newBlackStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newColorStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">              <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isVisuallyEqual<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\">: slightlyLighterBlack)}.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #98C379\">&quot;Original drawing had <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">originalBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes (should be 0 if all were changed).&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newColorStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> strokes with the new color.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/------------<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442\u0441\u044f, \u043d\u043e \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0430\u044f \u043f\u0435\u0447\u0430\u0442\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c <strong>\u0447\u0435\u0440\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 <\/strong>\u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXc8v_4PsOMIfbZqeyrmzDLGTW2OLngZGvATaxLFFHHPLfh3fbAeXR5FihE7PXVNGZvw-vxhGNb8-k66PoPKA8NocNaogPdmsbVNg0cwKB1tXjUdUVTMgh2pzLnqbeaVjw1IYhEr?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\" style=\"width:281px;height:auto\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b\u0438 strokes \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c drawing, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c strokes \u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c drawing \u0438 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e strokes \u0441 \u043d\u043e\u0432\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c drawing:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXf-IR24xD2r_bL9EFhuP1vMu_XsByZK508d1Lbn_X5fxEBTp1lIN1BywUw0wzeGYSNc1s0zEdjOShp75y8udY9F4A9liKUaw7-dbkcQ9GPDnffRAy5vZD1DkfoilHBjNt2W0Van?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e strokes <strong>\u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 <\/strong>\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u0440\u0430\u0432\u043d\u043e<strong> \u043e\u0442 1 \u0434\u043e 5<\/strong>,&nbsp; \u043f\u043e\u0441\u043b\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438\u0445 \u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c, \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e strokes <strong>\u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430<\/strong> \u043f\u043e\u0441\u043b\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0432\u043d\u043e <strong>0<\/strong>, a \u0432\u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e&nbsp; strokes <strong>\u043d\u043e\u0432\u043e\u0433\u043e <\/strong>( \u0432\u0437\u0430\u043c\u0435\u043d \u0447\u0435\u0440\u043d\u043e\u0433\u043e)&nbsp; <strong>\u0446\u0432\u0435\u0442\u0430 <\/strong>\u0434\u043e\u043b\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f<strong> \u043e\u0442 1 \u0434\u043e 5,<\/strong>&nbsp; \u043d\u043e \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0440\u0430\u0432\u043d\u044b\u043c<strong> 0.<\/strong><\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412 \u044d\u0442\u043e\u043c \u0438 \u043e\u0448\u0438\u0431\u043a\u0430.&nbsp;<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430 \u043a\u043e\u0434, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e&nbsp; strokes \u043d\u043e\u0432\u043e\u0433\u043e&nbsp; \u0446\u0432\u0435\u0442\u0430 (\u0432\u0437\u0430\u043c\u0435\u043d <strong>\u0447\u0435\u0440\u043d\u043e\u0433\u043e)<\/strong>:<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly> let newColorStrokes = modifiedDrawing.strokes.filter {       \n                                   $0.ink.color.isEqual(slightlyLighterBlack)}.count\n        print(\"Modified drawing has \\(newColorStrokes) strokes with the new color.\")<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newColorStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> {       <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                   <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #56B6C2\">isEqual<\/span><span style=\"color: #ABB2BF\">(slightlyLighterBlack)}.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newColorStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> strokes with the new color.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 isEqual \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u0446\u0432\u0435\u0442\u0430 slightlyLighterBlack, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0422\u0418\u041f UIExtendedGrayColorSpace:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXciiVVWiuvyArfwRxuaOtqZz2gA4Zqb7MRkpny7NlSaXa4GzYLZBA8pNkfizdiXPXp3uM2qAUA7rB9pH9KsA9-KQ_Baiuk35OwswU88H2ThIvJL3PeomIY9pTnMPRaJuHVLNhd9?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">&#8230; a \u0443 modifiedDrawing.strokes.map {$0.ink.color } b\u043c\u0435\u0435\u0442 \u0422\u0418\u041f: UIExtendedSRGBColorSpace:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXfENk99QBYJQVytwtd20JbvQiC9Zk8ZcQVBGm9YBzjVfOQMLNHOO6pPwhnq8ZZXPHfsCBysCNJdz6lYczLoy0yTssx9XUG524P8fF5vacVYI9rcsx1JyVXLe3t5yKytxVYnm7UEog?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0421\u043e\u043e\u0431\u0449\u0430\u0435\u043c Gemini 2.5 Pro \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0438 \u043f\u0440\u043e\u0441\u0438\u043c \u0441\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434:<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u043e\u0432 Colors, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u0432 \u0446\u0432\u0435\u0442\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430\u0445:<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXcJQxPzqsB8xNteCoXo3FYZe5yEOpMBYbsMnTU_upF6wCi_IzfZD-H-G8LalPpjJwr5WkzErdehX4U5T8xy35sa4giU7nDZ46BWYFG7nLq2OJQbw-49flK650cAAw-mpL4OLHsjGA?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-04-at-18.38.34.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"197\" src=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-04-at-18.38.34-1024x197.png\" alt=\"\" class=\"wp-image-17063\" srcset=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-04-at-18.38.34-1024x197.png 1024w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-04-at-18.38.34-300x58.png 300w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-04-at-18.38.34-768x148.png 768w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-04-at-18.38.34-500x96.png 500w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-04-at-18.38.34.png 1436w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412\u044b \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0439 \u0438 \u0442\u043e\u043d\u043a\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 UIColor! \u0426\u0432\u0435\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e UIColor \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0446\u0432\u0435\u0442 UIColor \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0438 \u043a\u0430\u043a \u043e\u043d \u0431\u044b\u043b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u0438\u043b\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 \u0446\u0432\u0435\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e UIColor(white:alpha:), \u043e\u043d \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u043e\u0442\u0442\u0435\u043d\u043a\u043e\u0432 \u0441\u0435\u0440\u043e\u0433\u043e (UIExtendedGrayColorSpace). \u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u043e\u0433\u0434\u0430 PencilKit (\u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a Core Graphics \u0438\u043b\u0438 UIKit drawing) \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u043b\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0446\u0432\u0435\u0442\u0430, \u043e\u043d \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0438\u0445 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e RGB, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 sRGB (UIExtendedSRGBColorSpace).<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0438\u0434 \u0446\u0432\u0435\u0442\u043e\u0432 UIColor \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u0435\u043d, isEqual: \u0432\u0435\u0440\u043d\u0435\u0442 false, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0431\u0430\u0437\u043e\u0432\u043e\u0435 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u041a\u0430\u043a \u043d\u0430\u0434\u0435\u0436\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0446\u0432\u0435\u0442\u0430, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f \u0432 \u0446\u0432\u0435\u0442\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430\u0445:<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0421\u0430\u043c\u044b\u0439 \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0434\u0432\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 UIColor \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0446\u0432\u0435\u0442, \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c:<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0439\u0442\u0435 \u043e\u0431\u0430 \u0446\u0432\u0435\u0442\u0430 \u0432 \u043e\u0431\u0449\u0435\u0435 \u043a\u0430\u043d\u043e\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, sRGB).<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435 \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u044d\u0442\u043e\u043c \u043e\u0431\u0449\u0435\u043c \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435, \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0434\u043e\u043f\u0443\u0441\u043a \u0438\u0437-\u0437\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043d\u0435\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0435\u0439 \u0447\u0438\u0441\u0435\u043b \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/span><\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 extension \u0434\u043b\u044f UIColor \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e isVisuallyEqual(to: UIColor, tolerance:) &nbsp; -&gt; Bool:<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>extension UIColor {\n\/\/ Check if this color is visually equal to another color, considering color spaces\n        func isVisuallyEqual(to otherColor: UIColor, tolerance: CGFloat = 0.001) -> Bool {\n            guard let srgbSelf = self.convertToSRGB(),\n                  let srgbOther = otherColor.convertToSRGB() else {\n  \/\/ If conversion fails for either, consider them not equal for safety\n  \/\/ or handle as a direct isEqual if one conversion failed but not the other.\n                \/\/ Simplest is to return false if any conversion fails.\n                if self.isEqual(otherColor) { return true } \/\/ Fallback for simple cases\n                return false\n            }\n        var r1: CGFloat = 0, g1: CGFloat = 0, b1: CGFloat = 0, a1: CGFloat = 0\n        var r2: CGFloat = 0, g2: CGFloat = 0, b2: CGFloat = 0, a2: CGFloat = 0\n            srgbSelf.getRed(&amp;r1, green: &amp;g1, blue: &amp;b1, alpha: &amp;a1)\n            srgbOther.getRed(&amp;r2, green: &amp;g2, blue: &amp;b2, alpha: &amp;a2)\n            return abs(r1 - r2) &lt;= tolerance &amp;&amp;\n                   abs(g1 - g2) &lt;= tolerance &amp;&amp;\n                   abs(b1 - b2) &lt;= tolerance &amp;&amp;\n                   abs(a1 - a2) &lt;= tolerance\n        }\n    }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">extension<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">UIColor<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ Check if this color is visually equal to another color, considering color spaces<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">isVisuallyEqual<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">otherColor<\/span><span style=\"color: #ABB2BF\">: UIColor, <\/span><span style=\"color: #61AFEF; font-style: italic\">tolerance<\/span><span style=\"color: #ABB2BF\">: CGFloat <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0.001<\/span><span style=\"color: #ABB2BF\">) -&gt; <\/span><span style=\"color: #E5C07B\">Bool<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> srgbSelf = <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">convertToSRGB<\/span><span style=\"color: #ABB2BF\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                  <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> srgbOther = otherColor.<\/span><span style=\"color: #61AFEF\">convertToSRGB<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ If conversion fails for either, consider them not equal for safety<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ or handle as a direct isEqual if one conversion failed but not the other.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Simplest is to return false if any conversion fails.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">isEqual<\/span><span style=\"color: #ABB2BF\">(otherColor) { <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">true<\/span><span style=\"color: #ABB2BF\"> } <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Fallback for simple cases<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> r1: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">, g1<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\"> CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">, b1<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\"> CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">, a1<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\"> CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> r2: CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">, g2<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\"> CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">, b2<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\"> CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><span style=\"color: #ABB2BF\">, a2<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\"> CGFloat = <\/span><span style=\"color: #D19A66\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            srgbSelf.<\/span><span style=\"color: #61AFEF\">getRed<\/span><span style=\"color: #ABB2BF\">(&amp;r1, <\/span><span style=\"color: #61AFEF\">green<\/span><span style=\"color: #ABB2BF\">: &amp;g1, <\/span><span style=\"color: #61AFEF\">blue<\/span><span style=\"color: #ABB2BF\">: &amp;b1, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: &amp;a1)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            srgbOther.<\/span><span style=\"color: #61AFEF\">getRed<\/span><span style=\"color: #ABB2BF\">(&amp;r2, <\/span><span style=\"color: #61AFEF\">green<\/span><span style=\"color: #ABB2BF\">: &amp;g2, <\/span><span style=\"color: #61AFEF\">blue<\/span><span style=\"color: #ABB2BF\">: &amp;b2, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: &amp;a2)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">abs<\/span><span style=\"color: #ABB2BF\">(r1 - r2) &lt;= tolerance &amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #56B6C2\">abs<\/span><span style=\"color: #ABB2BF\">(g1 - g2) &lt;= tolerance &amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #56B6C2\">abs<\/span><span style=\"color: #ABB2BF\">(b1 - b2) &lt;= tolerance &amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #56B6C2\">abs<\/span><span style=\"color: #ABB2BF\">(a1 - a2) &lt;= tolerance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0430\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c isVisuallyEqual \u0432 \u043a\u043e\u0434\u0435 \u043f\u0435\u0447\u0430\u0442\u0438 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 recognizedText(in:)<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>modifiedDrawing.strokes.filter \n    { $0.ink.color.isVisuallyEqual(to: mildLighterBlack) }.count<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">filter<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    { <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isVisuallyEqual<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\">: mildLighterBlack) }.count<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0432\u043c\u0435\u0441\u0442\u043e:<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(1 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>modifiedDrawing.strokes.filter \n     { $0.ink.color.isEqual(slightlyLighterBlack) }.count<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">filter<\/span><span style=\"color: #ABB2BF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     { <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #56B6C2\">isEqual<\/span><span style=\"color: #ABB2BF\">(slightlyLighterBlack) }.count<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 recognizedText (in currentDrawing: PKDrawing) \u043f\u0435\u0447\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0446\u0432\u0435\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/-------------PRINT-----\n            let originalBlackStrokes = currentDrawing.strokes.filter { \n                     $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n            let newBlackStrokes = modifiedDrawing.strokes.filter { \n                     $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n            let newColorStrokes = modifiedDrawing.strokes.filter {\n                $0.ink.color.isVisuallyEqual(to: slightlyLighterBlack)}.count\n            \n  print(\"Original drawing had \\(originalBlackStrokes) black strokes.\")\n  print(\"Modified drawing has \\(newBlackStrokes) black strokes (should be 0 if all were changed).\")\n  print(\"Modified drawing has \\(newColorStrokes) strokes with the new color.\") \/\/------------<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/-------------PRINT-----<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> originalBlackStrokes = currentDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                     <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newBlackStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                     <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newColorStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isVisuallyEqual<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\">: slightlyLighterBlack)}.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Original drawing had <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">originalBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes (should be 0 if all were changed).&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newColorStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> strokes with the new color.&quot;<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/------------<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0418 \u043f\u0435\u0447\u0430\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043c\u0435\u043d\u0435 \u0446\u0432\u0435\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXfI-kULQ2Prj5cyiMtjHd6sRV7nNqRwEiFOjd92ROsA9QdSSx1-bAn95kTCSDf2b2Fxtl3wkZNmQuiPvBMc_sRSgBo_VJDCT-ZGQCkDC9jJXT9liLmeyXYwb-8OC7UAe2QwwmbD?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e strokes <strong>\u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430 <\/strong>\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e \u043c\u0435\u0440\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u0440\u0430\u0432\u043d\u043e<strong> \u043e\u0442 1 \u0434\u043e 5<\/strong>,&nbsp; \u043f\u043e\u0441\u043b\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438\u0445 \u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c, \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e strokes <strong>\u0447\u0435\u0440\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430<\/strong> \u043f\u043e\u0441\u043b\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0432\u043d\u043e <strong>0<\/strong>, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e&nbsp; strokes <strong>\u043d\u043e\u0432\u043e\u0433\u043e <\/strong>( \u0432\u0437\u0430\u043c\u0435\u043d \u0447\u0435\u0440\u043d\u043e\u0433\u043e)&nbsp; <strong>\u0446\u0432\u0435\u0442\u0430 <\/strong>\u0442\u0430\u043a\u0436\u0435 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f<strong> \u043e\u0442 1 \u0434\u043e 5.<\/strong><\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u0412\u044b\u0431\u043e\u0440 \u044f\u0437\u044b\u043a\u0430 \u0434\u043b\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u044b\u0431\u043e\u0440 \u044f\u0437\u044b\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0438 \u043e\u043f\u044f\u0442\u044c&nbsp; \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043c Gemini 2.5 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0434\u043b\u044f \u043d\u0430\u0441:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXebHzOb2WgtOMQmpYLrKJGS7P7uLYiU6n7akiYlLh24qAdTrGy1Ng3EjsRr50ytqDtRK-DN0Vf0XuEOoUWwcorOXN-WeZTHAbWsYZfwApuIMegmf6gsQ74TVrVQ-UMuXTc2cobzHA?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-03-at-20.36.57.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"341\" src=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-03-at-20.36.57-1024x341.png\" alt=\"\" class=\"wp-image-17060\" srcset=\"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-03-at-20.36.57-1024x341.png 1024w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-03-at-20.36.57-300x100.png 300w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-03-at-20.36.57-768x256.png 768w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-03-at-20.36.57-500x167.png 500w, https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/Screenshot-2025-06-03-at-20.36.57.png 1362w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0425\u043e\u0440\u043e\u0448\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c Picker \u0432 \u0432\u0430\u0448 SwiftUI ContentView, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u043b\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u044f\u0437\u044b\u043a \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f VNRecognizeTextRequest.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/span><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0412\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u0432 @State \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e supportedLanguages<\/span> <span style=\"font-weight: 400;\">\u0438\u0437 VNRecognizeTextRequest.supportedRecognitionLanguages(for:revision:).<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e @State selectedLanguage \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c Picker \u0432 \u0441\u0432\u043e\u0439 UI.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a selectedLanguage \u0432 DrawingView (\u0438 \u0435\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440 Coordinator), \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 VNRecognizeTextRequest.<\/span><\/li>\n<\/ol>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 <strong>ContentView.swift<\/strong>:<\/span><\/li>\n<\/ol>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>import SwiftUI\nimport PencilKit\nimport Vision \/\/ Don't forget to import Vision\n\n\/\/ 1. SwiftUI View to host everything\nstruct ContentView: View {\n    @State private var drawing = PKDrawing()\n    @State private var recognizedText: String = \"Draw something and text will appear here.\"\n    \/\/ This will hold the tool picker instance\n    @State private var toolPicker = PKToolPicker()\n    \n    \/\/ State for supported languages and the selected language\n    @State private var supportedLanguages: &#91;String&#93; = []\n    @State private var selectedLanguage: String = \"\" \/\/ Will be set to a default\n    \n    var body: some View {\n        NavigationView {\n            VStack {\n\/\/ --- Language Picker ---\n               HStack {\n                 Text(\"Language:\")\n                 if supportedLanguages.isEmpty {\n                     Text(\"Loading languages...\")\n                           .foregroundColor(.gray)\n                 } else {\n                   Picker(\"Select Language\", selection: $selectedLanguage) {\n                      ForEach(supportedLanguages, id: \\.self) { language in\n                           Text(Locale.current.localizedString(\n                                        forIdentifier: language) ?? language)\n                           .tag(language)\n                      }\n                   }\n                   .pickerStyle(MenuPickerStyle()) \/\/ Or .automatic, .wheel\n                   .disabled(supportedLanguages.isEmpty)\n                   }\n               }\n               .padding(.horizontal)\n\/\/ --- End Language Picker ---\n                Text(\"Recognized Text:\")\n                    .font(.headline)\n                TextEditor(text: .constant(recognizedText))                        \n                    .frame(height: 100)\n                    .border(Color.gray)\n                    .padding()\n                \n                Button(\"Clear Drawing\") {\n                    drawing = PKDrawing() \/\/ Reset the drawing\n                    recognizedText = \"Drawing cleared.\"\n                }\n                .padding()\n                Text(\"Canvas:\")\n                    .font(.headline)\n                DrawingView(drawing: $drawing, \n                            recognizedText: $recognizedText, \n                            toolPicker: $toolPicker,\n                selectedLanguage: $selectedLanguage) \/\/ &lt;-- Pass selected language\n                    .frame(maxWidth: .infinity, maxHeight: .infinity)\n                    .border(Color.blue)\n                    .padding()\n                \n                Button(\"Clear Drawing\") {\n                    drawing = PKDrawing() \/\/ Reset the drawing\n                    recognizedText = \"Drawing cleared.\"\n                }\n                .padding()\n            }\n            \/\/   .navigationTitle(\"Handwriting OCR\")\n            .navigationBarTitleDisplayMode(.inline)\n            .onAppear { loadSupportedLanguages() }\n        }\n    }\n    \n    private func loadSupportedLanguages() {\n        DispatchQueue.global(qos: .userInitiated).async {\n            do {\n      \/\/ Get supported languages for accurate recognition level and default revision\n                let languages = try VNRecognizeTextRequest () .supportedRecognitionLanguages()\n                DispatchQueue.main.async {\n                    self.supportedLanguages = languages\n      \/\/ Set a default language if available (e.g., English or the first one)\n        if let enUS = languages.first(where: { $0.starts(with: \"en-US\") }) {\n                        self.selectedLanguage = enUS\n                    } else if let firstLang = languages.first {\n                        self.selectedLanguage = firstLang\n                    } else {\n                        print(\"No supported languages found.\")\n                        self.selectedLanguage = \"\" \/\/ Fallback\n                    }\n                }\n            } catch {\n  print(\"Error fetching supported languages: \\(error.localizedDescription)\")\n                DispatchQueue.main.async {\n                    self.supportedLanguages = []\n                    self.selectedLanguage = \"\"\n                }\n            }\n        }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">SwiftUI<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">PencilKit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">import<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">Vision<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Don&#39;t forget to import Vision<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ 1. SwiftUI View to host everything<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">struct<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">ContentView<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">View <\/span><span style=\"color: #ABB2BF\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> drawing = <\/span><span style=\"color: #61AFEF\">PKDrawing<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognizedText: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Draw something and text will appear here.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ This will hold the tool picker instance<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> toolPicker = <\/span><span style=\"color: #61AFEF\">PKToolPicker<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ State for supported languages and the selected language<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> supportedLanguages: &#91;<\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\">&#93; = []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@State<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> selectedLanguage: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Will be set to a default<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> body: <\/span><span style=\"color: #C678DD\">some<\/span><span style=\"color: #ABB2BF\"> View {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">NavigationView<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #61AFEF\">VStack<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ --- Language Picker ---<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">               <\/span><span style=\"color: #61AFEF\">HStack<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                 <\/span><span style=\"color: #61AFEF\">Text<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Language:&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                 <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> supportedLanguages.isEmpty {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                     <\/span><span style=\"color: #61AFEF\">Text<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Loading languages...&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                           .<\/span><span style=\"color: #61AFEF\">foregroundColor<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">gray<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                 } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #61AFEF\">Picker<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Select Language&quot;<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">selection<\/span><span style=\"color: #ABB2BF\">: $selectedLanguage) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                      <\/span><span style=\"color: #61AFEF\">ForEach<\/span><span style=\"color: #ABB2BF\">(supportedLanguages, <\/span><span style=\"color: #61AFEF\">id<\/span><span style=\"color: #ABB2BF\">: \\.<\/span><span style=\"color: #C678DD\">self<\/span><span style=\"color: #ABB2BF\">) { language <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                           <\/span><span style=\"color: #61AFEF\">Text<\/span><span style=\"color: #ABB2BF\">(Locale.<\/span><span style=\"color: #E06C75\">current<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">localizedString<\/span><span style=\"color: #ABB2BF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                        <\/span><span style=\"color: #61AFEF\">forIdentifier<\/span><span style=\"color: #ABB2BF\">: language) ?? language)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                           .<\/span><span style=\"color: #61AFEF\">tag<\/span><span style=\"color: #ABB2BF\">(language)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                      }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   .<\/span><span style=\"color: #61AFEF\">pickerStyle<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">MenuPickerStyle<\/span><span style=\"color: #ABB2BF\">()) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or .automatic, .wheel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   .<\/span><span style=\"color: #61AFEF\">disabled<\/span><span style=\"color: #ABB2BF\">(supportedLanguages.isEmpty)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">               }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">               .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">horizontal<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ --- End Language Picker ---<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">Text<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Recognized Text:&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">font<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">headline<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">TextEditor<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">text<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #61AFEF\">constant<\/span><span style=\"color: #ABB2BF\">(recognizedText))                        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">frame<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">height<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">100<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">border<\/span><span style=\"color: #ABB2BF\">(Color.<\/span><span style=\"color: #E06C75\">gray<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">Button<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Clear Drawing&quot;<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    drawing = <\/span><span style=\"color: #61AFEF\">PKDrawing<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Reset the drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    recognizedText = <\/span><span style=\"color: #98C379\">&quot;Drawing cleared.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">Text<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Canvas:&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">font<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">headline<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">DrawingView<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">drawing<\/span><span style=\"color: #ABB2BF\">: $drawing, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                            <\/span><span style=\"color: #61AFEF\">recognizedText<\/span><span style=\"color: #ABB2BF\">: $recognizedText, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                            <\/span><span style=\"color: #61AFEF\">toolPicker<\/span><span style=\"color: #ABB2BF\">: $toolPicker,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">selectedLanguage<\/span><span style=\"color: #ABB2BF\">: $selectedLanguage) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ &lt;-- Pass selected language<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">frame<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">maxWidth<\/span><span style=\"color: #ABB2BF\">: .infinity, <\/span><span style=\"color: #61AFEF\">maxHeight<\/span><span style=\"color: #ABB2BF\">: .infinity)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">border<\/span><span style=\"color: #ABB2BF\">(Color.<\/span><span style=\"color: #E06C75\">blue<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #61AFEF\">Button<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Clear Drawing&quot;<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    drawing = <\/span><span style=\"color: #61AFEF\">PKDrawing<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Reset the drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    recognizedText = <\/span><span style=\"color: #98C379\">&quot;Drawing cleared.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                .<\/span><span style=\"color: #61AFEF\">padding<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/   .navigationTitle(&quot;Handwriting OCR&quot;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            .<\/span><span style=\"color: #61AFEF\">navigationBarTitleDisplayMode<\/span><span style=\"color: #ABB2BF\">(.<\/span><span style=\"color: #E06C75\">inline<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            .<\/span><span style=\"color: #61AFEF\">onAppear<\/span><span style=\"color: #ABB2BF\"> { <\/span><span style=\"color: #61AFEF\">loadSupportedLanguages<\/span><span style=\"color: #ABB2BF\">() }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">loadSupportedLanguages<\/span><span style=\"color: #ABB2BF\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        DispatchQueue.<\/span><span style=\"color: #61AFEF\">global<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">qos<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #E06C75\">userInitiated<\/span><span style=\"color: #ABB2BF\">).<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">do<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Get supported languages for accurate recognition level and default revision<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> languages = <\/span><span style=\"color: #C678DD\">try<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">VNRecognizeTextRequest<\/span><span style=\"color: #ABB2BF\"> () .<\/span><span style=\"color: #61AFEF\">supportedRecognitionLanguages<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">supportedLanguages<\/span><span style=\"color: #ABB2BF\"> = languages<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Set a default language if available (e.g., English or the first one)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> enUS = languages.<\/span><span style=\"color: #56B6C2\">first<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">where<\/span><span style=\"color: #ABB2BF\">: { <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">starts<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">with<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #98C379\">&quot;en-US&quot;<\/span><span style=\"color: #ABB2BF\">) }) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">selectedLanguage<\/span><span style=\"color: #ABB2BF\"> = enUS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> firstLang = languages.<\/span><span style=\"color: #56B6C2\">first<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">selectedLanguage<\/span><span style=\"color: #ABB2BF\"> = firstLang<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;No supported languages found.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">selectedLanguage<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;&quot;<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Fallback<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            } <\/span><span style=\"color: #C678DD\">catch<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Error fetching supported languages: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">supportedLanguages<\/span><span style=\"color: #ABB2BF\"> = []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">selectedLanguage<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 <strong>DrawingView.swift<\/strong>:<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(2 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/ 2. UIViewRepresentable for PKCanvasView\nstruct DrawingView: UIViewRepresentable {\n    @Binding var drawing: PKDrawing\n    @Binding var recognizedText: String\n    @Binding var toolPicker: PKToolPicker \/\/ Pass the tool picker\n    \n    @Binding var selectedLanguage: String \/\/ &lt;-- Receive selected language\n\n    func makeUIView(context: Context) -> PKCanvasView {\n        let canvasView = PKCanvasView()\n        canvasView.drawing = drawing\n        canvasView.delegate = context.coordinator\n        canvasView.drawingPolicy = .anyInput \/\/ Or .pencilOnly for Apple Pencil only\n        canvasView.backgroundColor = .clear \/\/ Or any other color\n        canvasView.isOpaque = false\n        \/\/ Show the tool picker\n        toolPicker.addObserver(canvasView) \/\/ Observe tool changes\n        toolPicker.setVisible(true, forFirstResponder: canvasView)\n        canvasView.becomeFirstResponder() \/\/ Important to make the canvas active for the tool picker\n        return canvasView\n    }\n\n    func updateUIView(_ uiView: PKCanvasView, context: Context) {\n   \/\/ Update the drawing if it's changed from outside (e.g., by the \"Clear Drawing\" button)\n        if uiView.drawing != drawing {\n             uiView.drawing = drawing\n        }\n  \/\/ If the selected language changes, we might want to trigger a re-recognition\n  \/\/ or just ensure the coordinator knows about the new language for the *next* recognition.\n  \/\/ For simplicity, the coordinator will use the binding directly when a new drawing change \n                context.coordinator.updateSelectedLanguage(selectedLanguage)\n    }\n\n    func makeCoordinator() -> Coordinator {\n       \/\/ Coordinator(self, recognizedText: $recognizedText)\n        Coordinator(self, recognizedText: $recognizedText, \n                          selectedLanguage: selectedLanguage)\n    }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ABB2BF\">\/ <\/span><span style=\"color: #D19A66\">2<\/span><span style=\"color: #ABB2BF\">. UIViewRepresentable <\/span><span style=\"color: #C678DD\">for<\/span><span style=\"color: #ABB2BF\"> PKCanvasView<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C678DD\">struct<\/span><span style=\"color: #ABB2BF\"> DrawingView<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\"> UIViewRepresentable {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> drawing: PKDrawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognizedText: <\/span><span style=\"color: #E5C07B\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> toolPicker: PKToolPicker <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Pass the tool picker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> selectedLanguage: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ &lt;-- Receive selected language<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">makeUIView<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF; font-style: italic\">context<\/span><span style=\"color: #ABB2BF\">: Context) -&gt; PKCanvasView {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> canvasView = <\/span><span style=\"color: #61AFEF\">PKCanvasView<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\"> = drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">delegate<\/span><span style=\"color: #ABB2BF\"> = context.<\/span><span style=\"color: #E06C75\">coordinator<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">drawingPolicy<\/span><span style=\"color: #ABB2BF\"> = .<\/span><span style=\"color: #E06C75\">anyInput<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or .pencilOnly for Apple Pencil only<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">backgroundColor<\/span><span style=\"color: #ABB2BF\"> = .<\/span><span style=\"color: #E06C75\">clear<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or any other color<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #E06C75\">isOpaque<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Show the tool picker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        toolPicker.<\/span><span style=\"color: #61AFEF\">addObserver<\/span><span style=\"color: #ABB2BF\">(canvasView) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Observe tool changes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        toolPicker.<\/span><span style=\"color: #61AFEF\">setVisible<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66\">true<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">forFirstResponder<\/span><span style=\"color: #ABB2BF\">: canvasView)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        canvasView.<\/span><span style=\"color: #61AFEF\">becomeFirstResponder<\/span><span style=\"color: #ABB2BF\">() <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Important to make the canvas active for the tool picker<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> canvasView<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">updateUIView<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">_<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">uiView<\/span><span style=\"color: #ABB2BF\">: PKCanvasView, <\/span><span style=\"color: #61AFEF; font-style: italic\">context<\/span><span style=\"color: #ABB2BF\">: Context) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">   <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Update the drawing if it&#39;s changed from outside (e.g., by the &quot;Clear Drawing&quot; button)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> uiView.drawing != drawing {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">             uiView.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\"> = drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ If the selected language changes, we might want to trigger a re-recognition<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ or just ensure the coordinator knows about the new language for the *next* recognition.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">  <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ For simplicity, the coordinator will use the binding directly when a new drawing change <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                context.<\/span><span style=\"color: #E06C75\">coordinator<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">updateSelectedLanguage<\/span><span style=\"color: #ABB2BF\">(selectedLanguage)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">makeCoordinator<\/span><span style=\"color: #ABB2BF\">() -&gt; Coordinator {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">       <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Coordinator(self, recognizedText: $recognizedText)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #61AFEF\">Coordinator<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">recognizedText<\/span><span style=\"color: #ABB2BF\">: $recognizedText, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                          <\/span><span style=\"color: #61AFEF\">selectedLanguage<\/span><span style=\"color: #ABB2BF\">: selectedLanguage)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 <strong>Coordinator.swift<\/strong>:<\/span><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:.75rem;font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#abb2bf;--cbp-line-number-width:calc(3 * 0.6 * .75rem);line-height:1rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282c34\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#abb2bf;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>\/\/ 3. Coordinator to handle PKCanvasViewDelegate methods\n    class Coordinator: NSObject, PKCanvasViewDelegate {\n        var parent: DrawingView\n        @Binding var recognizedText: String\n        private var recognitionTask: DispatchWorkItem? \/\/ To debounce recognition\n        \n        private var currentSelectedLanguage: String \/\/ Store the language locally in Coordinator\n        init(_ parent: DrawingView, recognizedText: Binding&lt;String>, \n             selectedLanguage: String) {\n            self.parent = parent\n            self._recognizedText = recognizedText\n            self.currentSelectedLanguage = selectedLanguage\n        }\n        \n\/\/ Method to update language if it changes from ContentView\n        func updateSelectedLanguage(_ newLanguage: String) {\n            self.currentSelectedLanguage = newLanguage\n\/\/ Optional: If you want to re-recognize immediately when language changes,\n\/\/ you could call recognizeText here, but it might be too frequent.\n\/\/ It's usually better to apply the new language on the next drawing change.\n        }\n        func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {\n        \/\/ Update the parent's drawing binding\n            parent.drawing = canvasView.drawing\n        \/\/ Debounce recognition: Cancel previous task and schedule a new one\n            recognitionTask?.cancel()\n            let task = DispatchWorkItem { &#91;weak self&#93; in\n              \/\/  self?.recognizeText(in: canvasView.drawing)\n                guard let self = self else { return }\n                self.recognizeText(in: canvasView.drawing,\n                                   language: self.currentSelectedLanguage) \/\/ &lt;-- Use selected language\n            }\n            self.recognitionTask = task\n    \/\/ Perform recognition after a short delay to avoid excessive processing\n            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: task)\n        }\n        \/\/ Updated recognizeText to accept language\n        private func recognizeText(in currentDrawing: PKDrawing, \n                                   language: String) {\n            \n            \/\/ Ensure there's something to recognize\n            guard !currentDrawing.bounds.isEmpty else {\n                DispatchQueue.main.async {\n                    self.recognizedText = \"Canvas is empty.\"\n                }\n                return\n            }\n            \/\/-------------------\n            \/\/ 1. Get the current drawing from the canvas or state\n            \/\/ Or currentDrawing\n            \/\/ 2. Define the target \"not so black\" color\n            let slightlyLighterBlack = UIColor(white: 0.15, alpha: 1.0) \/\/ A very dark gray\n            \/\/ 3. Modify the drawing\n            let modifiedDrawing = modifyBlackStrokes(in: currentDrawing,\n                                         to: slightlyLighterBlack,\n                                         blacknessTolerance: 0.1)\n            \/\/-------------PRINT-----\n            let originalBlackStrokes = currentDrawing.strokes.filter { \n                   $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n            let newBlackStrokes = modifiedDrawing.strokes.filter { \n                   $0.ink.color.isEssentiallyBlack(tolerance: 0.1) }.count\n            let newColorStrokes = modifiedDrawing.strokes.filter {\n                $0.ink.color.isVisuallyEqual(to: slightlyLighterBlack)}.count\n            \nprint(\"Original drawing had \\(originalBlackStrokes) black strokes.\")\nprint(\"Modified drawing has \\(newBlackStrokes) black strokes (should be 0 if all were changed).\")\nprint(\"Modified drawing has \\(newColorStrokes) strokes with the new color.\")\n            \/\/------------\n            \/\/ 1. Get an image from the PKDrawing\n      \/\/ Use a slightly larger bounds for the image to ensure all strokes are captured,\n      \/\/ especially if they go near the edges of the tight `drawing.bounds`.\n            let imageRect = currentDrawing.bounds.insetBy(dx: -20, dy: -20)    \n      \/\/ Add some padding\n            let image = modifiedDrawing.image(from: imageRect, scale: UIScreen.main.scale)\n            \/\/ 2. Create a Vision text recognition request\n            let request = VNRecognizeTextRequest { (request, error) in\n                if let error = error {\n        print(\"Error recognizing text: \\(error.localizedDescription)\")\n                    DispatchQueue.main.async {\n                self.recognizedText = \"Error: \\(error.localizedDescription)\"\n                    }\n                    return\n                }\n                guard let observations = \n                        request.results as? &#91;VNRecognizedTextObservation&#93;, \n                        !observations.isEmpty else {\n                    DispatchQueue.main.async {\n                        self.recognizedText = \"No text recognized.\"\n                    }\n                    return\n                }\n                let recognizedStrings = observations.compactMap { observation in\n                    \/\/ Return the string with the highest confidence.\n                    observation.topCandidates(1).first?.string\n                }\n                \n                DispatchQueue.main.async {\n                    self.recognizedText = recognizedStrings.joined(separator: \"\\n\")\n                    if self.recognizedText.isEmpty {\n                         self.recognizedText = \n                                           \"No text confidently recognized.\"\n                    }\n                }\n            }\n            \/\/ Optional: Configure the request\n            request.recognitionLevel = .accurate\/\/.fast \/\/ .accurate or .fast\n            request.usesLanguageCorrection = true\n          \/\/  request.recognitionLanguages = &#91;\"en-US\"&#93; \/\/ Specify languages if needed\n            if !language.isEmpty { \n        \/\/ Only set if a language is actually selected\n                  request.recognitionLanguages = &#91;language&#93; \/\/ &lt;-- Set the selected language\n                  print(\"Using language for OCR: \\(language)\")\n            } else {\n                  request.recognitionLanguages = &#91;\"en-US\"&#93;\n      print(\"No specific language selected for OCR, using Vision's default.\")\n                      }\n            \/\/ Very important - set this to true for handwriting\n            if #available(iOS 16.0, *) {\n                request.automaticallyDetectsLanguage = false\n                request.revision = VNRecognizeTextRequestRevision3\n            }\n            \/\/ 3. Create a request handler and perform the request\n           guard let cgImage = image.cgImage else {\n                print(\"Failed to get CGImage from drawing.\")\n                DispatchQueue.main.async {\n                    self.recognizedText = \"Error processing drawing.\"\n                }\n                return\n            }\n            let handler = VNImageRequestHandler(cgImage: cgImage, \n                                                options: &#91;:&#93;)\n            DispatchQueue.global(qos: .userInitiated).async {\n                do {\n                    try handler.perform(&#91;request&#93;)\n                } catch {\n    print(\"Failed to perform recognition: \\(error.localizedDescription)\")\n                    DispatchQueue.main.async {\n                        self.recognizedText = \"Recognition failed.\"\n                    }\n                }\n            }\n        }\n     \n        func modifyBlackStrokes(in drawing: PKDrawing,\n                                to newColor: UIColor,\n                                blacknessTolerance: CGFloat = 0.05) -> PKDrawing {\n            var modifiedStrokes: &#91;PKStroke&#93; = []\n            for originalStroke in drawing.strokes {\n    \/\/ Check if the original stroke's ink color is essentially black\n                if originalStroke.ink.color.isEssentiallyBlack(tolerance: blacknessTolerance) {\n    \/\/ Create a new ink with the new color, keeping other ink properties\n                    let newInk = PKInk(originalStroke.ink.inkType, \n                                       color: newColor)\n                    \n    \/\/ Create a new stroke with the new ink but the same path and transform\n                    let newStroke = PKStroke(ink: newInk, \n                                             path: originalStroke.path, \n                                             transform: \n                                                    originalStroke.transform, \n                                             mask: originalStroke.mask)\n                    modifiedStrokes.append(newStroke)\n                } else {\n                    \/\/ If the stroke is not black, keep it as is\n                    modifiedStrokes.append(originalStroke)\n                }\n            }\n            return PKDrawing(strokes: modifiedStrokes)\n        }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki one-dark-pro\" style=\"background-color: #282c34\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ 3. Coordinator to handle PKCanvasViewDelegate methods<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #C678DD\">class<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">Coordinator<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">NSObject<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #E5C07B\">PKCanvasViewDelegate <\/span><span style=\"color: #ABB2BF\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> parent: DrawingView<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">@Binding<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognizedText: <\/span><span style=\"color: #E5C07B\">String<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> recognitionTask: DispatchWorkItem? <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ To debounce recognition<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> currentSelectedLanguage: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Store the language locally in Coordinator<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">init<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">_<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">parent<\/span><span style=\"color: #ABB2BF\">: DrawingView, <\/span><span style=\"color: #61AFEF; font-style: italic\">recognizedText<\/span><span style=\"color: #ABB2BF\">: Binding&lt;<\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\">&gt;, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">             <\/span><span style=\"color: #61AFEF; font-style: italic\">selectedLanguage<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">parent<\/span><span style=\"color: #ABB2BF\"> = parent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">_recognizedText<\/span><span style=\"color: #ABB2BF\"> = recognizedText<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">currentSelectedLanguage<\/span><span style=\"color: #ABB2BF\"> = selectedLanguage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ Method to update language if it changes from ContentView<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">updateSelectedLanguage<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">_<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">newLanguage<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">currentSelectedLanguage<\/span><span style=\"color: #ABB2BF\"> = newLanguage<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ Optional: If you want to re-recognize immediately when language changes,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ you could call recognizeText here, but it might be too frequent.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #7F848E; font-style: italic\">\/\/ It&#39;s usually better to apply the new language on the next drawing change.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">canvasViewDrawingDidChange<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">_<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">canvasView<\/span><span style=\"color: #ABB2BF\">: PKCanvasView) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Update the parent&#39;s drawing binding<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            parent.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\"> = canvasView.<\/span><span style=\"color: #E06C75\">drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Debounce recognition: Cancel previous task and schedule a new one<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            recognitionTask?.<\/span><span style=\"color: #61AFEF\">cancel<\/span><span style=\"color: #ABB2BF\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> task = <\/span><span style=\"color: #61AFEF\">DispatchWorkItem<\/span><span style=\"color: #ABB2BF\"> { &#91;<\/span><span style=\"color: #C678DD\">weak<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">&#93; <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">              <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/  self?.recognizeText(in: canvasView.drawing)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> { <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">recognizeText<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\">: canvasView.<\/span><span style=\"color: #E06C75\">drawing<\/span><span style=\"color: #ABB2BF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                   <\/span><span style=\"color: #61AFEF\">language<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">currentSelectedLanguage<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ &lt;-- Use selected language<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognitionTask<\/span><span style=\"color: #ABB2BF\"> = task<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Perform recognition after a short delay to avoid excessive processing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">asyncAfter<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">deadline<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #61AFEF\">now<\/span><span style=\"color: #ABB2BF\">() + <\/span><span style=\"color: #D19A66\">0.5<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">execute<\/span><span style=\"color: #ABB2BF\">: task)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Updated recognizeText to accept language<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">private<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">recognizeText<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">currentDrawing<\/span><span style=\"color: #ABB2BF\">: PKDrawing, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                   <\/span><span style=\"color: #61AFEF; font-style: italic\">language<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #E5C07B\">String<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Ensure there&#39;s something to recognize<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> !currentDrawing.bounds.isEmpty <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Canvas is empty.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/-------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 1. Get the current drawing from the canvas or state<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Or currentDrawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 2. Define the target &quot;not so black&quot; color<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> slightlyLighterBlack = <\/span><span style=\"color: #61AFEF\">UIColor<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">white<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.15<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">alpha<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">1.0<\/span><span style=\"color: #ABB2BF\">) <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ A very dark gray<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 3. Modify the drawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> modifiedDrawing = <\/span><span style=\"color: #61AFEF\">modifyBlackStrokes<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\">: currentDrawing,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                         <\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\">: slightlyLighterBlack,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                         <\/span><span style=\"color: #61AFEF\">blacknessTolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/-------------PRINT-----<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> originalBlackStrokes = currentDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newBlackStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                   <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">0.1<\/span><span style=\"color: #ABB2BF\">) }.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newColorStrokes = modifiedDrawing.<\/span><span style=\"color: #E06C75\">strokes<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #56B6C2\">filter<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">$0<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.color.<\/span><span style=\"color: #61AFEF\">isVisuallyEqual<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\">: slightlyLighterBlack)}.count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Original drawing had <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">originalBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newBlackStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> black strokes (should be 0 if all were changed).&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Modified drawing has <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">newColorStrokes<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\"> strokes with the new color.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 1. Get an image from the PKDrawing<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Use a slightly larger bounds for the image to ensure all strokes are captured,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ especially if they go near the edges of the tight `drawing.bounds`.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> imageRect = currentDrawing.<\/span><span style=\"color: #E06C75\">bounds<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">insetBy<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">dx<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">-20<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #61AFEF\">dy<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #D19A66\">-20<\/span><span style=\"color: #ABB2BF\">)    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Add some padding<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> image = modifiedDrawing.image(<\/span><span style=\"color: #61AFEF\">from<\/span><span style=\"color: #ABB2BF\">: imageRect, <\/span><span style=\"color: #61AFEF\">scale<\/span><span style=\"color: #ABB2BF\">: UIScreen.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">scale<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 2. Create a Vision text recognition request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> request = <\/span><span style=\"color: #61AFEF\">VNRecognizeTextRequest<\/span><span style=\"color: #ABB2BF\"> { (request, error) <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> error = error {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Error recognizing text: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Error: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> observations = <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        request.results as? &#91;VNRecognizedTextObservation&#93;, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        !observations.isEmpty <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;No text recognized.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> recognizedStrings = observations.<\/span><span style=\"color: #61AFEF\">compactMap<\/span><span style=\"color: #ABB2BF\"> { observation <\/span><span style=\"color: #C678DD\">in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Return the string with the highest confidence.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    observation.<\/span><span style=\"color: #61AFEF\">topCandidates<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #D19A66\">1<\/span><span style=\"color: #ABB2BF\">).first?.<\/span><span style=\"color: #E06C75\">string<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = recognizedStrings.<\/span><span style=\"color: #56B6C2\">joined<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">separator<\/span><span style=\"color: #ABB2BF\">: <\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #56B6C2\">\\n<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.recognizedText.isEmpty {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                         <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                           <\/span><span style=\"color: #98C379\">&quot;No text confidently recognized.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Optional: Configure the request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            request.<\/span><span style=\"color: #E06C75\">recognitionLevel<\/span><span style=\"color: #ABB2BF\"> = .<\/span><span style=\"color: #E06C75\">accurate<\/span><span style=\"color: #7F848E; font-style: italic\">\/\/.fast \/\/ .accurate or .fast<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            request.<\/span><span style=\"color: #E06C75\">usesLanguageCorrection<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">          <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/  request.recognitionLanguages = &#91;&quot;en-US&quot;&#93; \/\/ Specify languages if needed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> !language.isEmpty { <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Only set if a language is actually selected<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                  request.<\/span><span style=\"color: #E06C75\">recognitionLanguages<\/span><span style=\"color: #ABB2BF\"> = &#91;language&#93; <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ &lt;-- Set the selected language<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                  <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Using language for OCR: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">language<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                  request.<\/span><span style=\"color: #E06C75\">recognitionLanguages<\/span><span style=\"color: #ABB2BF\"> = &#91;<\/span><span style=\"color: #98C379\">&quot;en-US&quot;<\/span><span style=\"color: #ABB2BF\">&#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">      <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;No specific language selected for OCR, using Vision&#39;s default.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                      }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Very important - set this to true for handwriting<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #56B6C2\">#available<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #C678DD\">iOS<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">16.0<\/span><span style=\"color: #ABB2BF\">, <\/span><span style=\"color: #C678DD\">*<\/span><span style=\"color: #ABB2BF\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                request.<\/span><span style=\"color: #E06C75\">automaticallyDetectsLanguage<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #D19A66\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                request.<\/span><span style=\"color: #E06C75\">revision<\/span><span style=\"color: #ABB2BF\"> = VNRecognizeTextRequestRevision3<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ 3. Create a request handler and perform the request<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">           <\/span><span style=\"color: #C678DD\">guard<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> cgImage = image.cgImage <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Failed to get CGImage from drawing.&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Error processing drawing.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">return<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> handler = <\/span><span style=\"color: #61AFEF\">VNImageRequestHandler<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">cgImage<\/span><span style=\"color: #ABB2BF\">: cgImage, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                                <\/span><span style=\"color: #61AFEF\">options<\/span><span style=\"color: #ABB2BF\">: &#91;<\/span><span style=\"color: #C678DD\">:<\/span><span style=\"color: #ABB2BF\">&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            DispatchQueue.<\/span><span style=\"color: #61AFEF\">global<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">qos<\/span><span style=\"color: #ABB2BF\">: .<\/span><span style=\"color: #E06C75\">userInitiated<\/span><span style=\"color: #ABB2BF\">).<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">do<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">try<\/span><span style=\"color: #ABB2BF\"> handler.<\/span><span style=\"color: #61AFEF\">perform<\/span><span style=\"color: #ABB2BF\">(&#91;request&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                } <\/span><span style=\"color: #C678DD\">catch<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #56B6C2\">print<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #98C379\">&quot;Failed to perform recognition: <\/span><span style=\"color: #C678DD\">\\(<\/span><span style=\"color: #ABB2BF\">error.<\/span><span style=\"color: #E06C75\">localizedDescription<\/span><span style=\"color: #C678DD\">)<\/span><span style=\"color: #98C379\">&quot;<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    DispatchQueue.<\/span><span style=\"color: #E06C75\">main<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #61AFEF\">async<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                        <\/span><span style=\"color: #E5C07B\">self<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">recognizedText<\/span><span style=\"color: #ABB2BF\"> = <\/span><span style=\"color: #98C379\">&quot;Recognition failed.&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">     <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        <\/span><span style=\"color: #C678DD\">func<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">modifyBlackStrokes<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">in<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">drawing<\/span><span style=\"color: #ABB2BF\">: PKDrawing,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                <\/span><span style=\"color: #61AFEF\">to<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #ABB2BF; font-style: italic\">newColor<\/span><span style=\"color: #ABB2BF\">: UIColor,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                <\/span><span style=\"color: #61AFEF; font-style: italic\">blacknessTolerance<\/span><span style=\"color: #ABB2BF\">: CGFloat <\/span><span style=\"color: #56B6C2\">=<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #D19A66\">0.05<\/span><span style=\"color: #ABB2BF\">) -&gt; PKDrawing {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">var<\/span><span style=\"color: #ABB2BF\"> modifiedStrokes: &#91;PKStroke&#93; = []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">for<\/span><span style=\"color: #ABB2BF\"> originalStroke <\/span><span style=\"color: #C678DD\">in<\/span><span style=\"color: #ABB2BF\"> drawing.strokes {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Check if the original stroke&#39;s ink color is essentially black<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                <\/span><span style=\"color: #C678DD\">if<\/span><span style=\"color: #ABB2BF\"> originalStroke.ink.color.<\/span><span style=\"color: #61AFEF\">isEssentiallyBlack<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">tolerance<\/span><span style=\"color: #ABB2BF\">: blacknessTolerance) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Create a new ink with the new color, keeping other ink properties<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newInk = <\/span><span style=\"color: #61AFEF\">PKInk<\/span><span style=\"color: #ABB2BF\">(originalStroke.<\/span><span style=\"color: #E06C75\">ink<\/span><span style=\"color: #ABB2BF\">.<\/span><span style=\"color: #E06C75\">inkType<\/span><span style=\"color: #ABB2BF\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                       <\/span><span style=\"color: #61AFEF\">color<\/span><span style=\"color: #ABB2BF\">: newColor)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ Create a new stroke with the new ink but the same path and transform<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #C678DD\">let<\/span><span style=\"color: #ABB2BF\"> newStroke = <\/span><span style=\"color: #61AFEF\">PKStroke<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">ink<\/span><span style=\"color: #ABB2BF\">: newInk, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                             <\/span><span style=\"color: #61AFEF\">path<\/span><span style=\"color: #ABB2BF\">: originalStroke.<\/span><span style=\"color: #E06C75\">path<\/span><span style=\"color: #ABB2BF\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                             <\/span><span style=\"color: #61AFEF\">transform<\/span><span style=\"color: #ABB2BF\">: <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                                    originalStroke.<\/span><span style=\"color: #E06C75\">transform<\/span><span style=\"color: #ABB2BF\">, <\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                                             <\/span><span style=\"color: #61AFEF\">mask<\/span><span style=\"color: #ABB2BF\">: originalStroke.<\/span><span style=\"color: #E06C75\">mask<\/span><span style=\"color: #ABB2BF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    modifiedStrokes.<\/span><span style=\"color: #56B6C2\">append<\/span><span style=\"color: #ABB2BF\">(newStroke)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                } <\/span><span style=\"color: #C678DD\">else<\/span><span style=\"color: #ABB2BF\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    <\/span><span style=\"color: #7F848E; font-style: italic\">\/\/ If the stroke is not black, keep it as is<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                    modifiedStrokes.<\/span><span style=\"color: #56B6C2\">append<\/span><span style=\"color: #ABB2BF\">(originalStroke)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">            <\/span><span style=\"color: #C678DD\">return<\/span><span style=\"color: #ABB2BF\"> <\/span><span style=\"color: #61AFEF\">PKDrawing<\/span><span style=\"color: #ABB2BF\">(<\/span><span style=\"color: #61AFEF\">strokes<\/span><span style=\"color: #ABB2BF\">: modifiedStrokes)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ABB2BF\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f:<\/strong><\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\"><strong>ContentView<\/strong>:<\/span><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">@State private var supportedLanguages: [String] = []: \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u043e\u0434\u043e\u0432 \u044f\u0437\u044b\u043a\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, &#171;en-US&#187;, &#171;fr-FR&#187;).<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">@State private var selectedLanguage: String = &#171;&#187;: \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u044f\u0437\u044b\u043a\u0430.<\/span><\/li>\n\n\n\n<li><strong>loadSupportedLanguages()<\/strong>:\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 .onAppear.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 VNRecognizeTextRequest.supportedRecognitionLanguages(for:revision:) \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430. \u042d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 (throws), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0430 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u0430 \u0432 \u0431\u043b\u043e\u043a do-catch.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 supportedLanguages \u200b\u200b\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f selectedLanguage (\u043f\u0440\u043e\u0431\u0443\u0435\u0442 &#171;en-US&#187;, \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439).<\/span><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>UI Picker<\/strong>:\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u0412 VStack \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f Picker.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041e\u043d \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f supportedLanguages.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">Locale.current.localizedString(forIdentifier: language) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0445 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u044f\u0437\u044b\u043a\u043e\u0432.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f @State \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f selectedLanguage \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u0430 (@Binding) \u043a selection Picker.<\/span><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f selectedLanguage \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a @Binding \u0432 DrawingView.<\/span><\/li>\n<\/ul>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">DrawingView (UIViewRepresentable):<\/span><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">@Binding var selectedLanguage: String: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u044f\u0437\u044b\u043a\u0430.<\/span><\/li>\n\n\n\n<li><strong>updateUIView(_:context:)<\/strong>: <\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442 context.coordinator.updateSelectedLanguage(selectedLanguage), \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0443 Coordinator \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u044f\u0437\u044b\u043a\u0430 \u0438\u0437 ContentView.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 selectedLanguage \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0443 Coordinator \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0435\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/span><\/li>\n<\/ul>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">DrawingView.Coordinator:<\/span><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>private var currentSelectedLanguage: String: \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u044f\u0437\u044b\u043a, \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u0437 DrawingView.<\/li>\n\n\n\n<li><strong>updateSelectedLanguage(_:)<\/strong>: \u041d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 DrawingView \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c currentSelectedLanguage \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u043e\u0440\u0430, \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u0432 ContentView \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f.<\/li>\n\n\n\n<li><strong>recognizeText(in:language:)<\/strong>:\n<ul class=\"wp-block-list\">\n<li><span style=\"font-weight: 400;\">\u041c\u0435\u0442\u043e\u0434 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 language: String.<\/span><\/li>\n\n\n\n<li><span style=\"font-weight: 400;\">\u042d\u0442\u043e\u0442 \u044f\u0437\u044b\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 request.recognitionLanguages \u200b\u200b= [language] \u0432 VNRecognizeTextRequest. \u0412\u0430\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 language \u043d\u0435 \u043f\u0443\u0441\u0442.<\/span><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><span style=\"font-weight: 400;\"><strong>canvasViewDrawingDidChange(_:):<\/strong> \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0438\u0441\u0443\u043d\u043a\u0430 drawing \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 recognizeText, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f self.currentSelectedLanguage.<\/span><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c Picker, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u0430\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u0437 \u044f\u0437\u044b\u043a\u043e\u0432, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 Vision OCR \u043d\u0430 \u0432\u0430\u0448\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435\/\u0432\u0435\u0440\u0441\u0438\u0438 \u041e\u0421. \u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0439 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430.<\/span><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a \u0438\u0437 Picker. \u041f\u0438\u0448\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u0438 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0430\u0445, \u0438 \u043e\u0431\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u044e\u0442\u0441\u044f:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXfyBTFDLnHz4LlK3yHFMcrv4idRTLVReqQJ1C7rL0NwhrApuO1D2BY41ZhokLHUDaxoLTyOPQ4swobN-iqEoKnCYu2B5CfVBbLnXh1gVPUzGA0Bf7oObxBTEr5fwn4YPqEuOgltlw?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0412\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0438 \u043d\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u044f\u0437\u044b\u043a \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u043e\u043d \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438:<\/span><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-rt.googleusercontent.com\/docsz\/AD_4nXeConUrO07wNlbMuPaLJEpGP1AX1JyM6PvBA5yLKqjuHxJXkIevlHrDkTXdGXUr_tl1T2m5Jq9JpnOWT3T6bHwfuxewi5jufmEVjpzrYakvrqMEFghOeN_OmuJAVbJ5gIVyRkZ19Q?key=-hILHRP3ZXjWhYxqVhGRrg\" alt=\"\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><span style=\"font-weight: 400;\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a SwiftUI\u00a0 \u0441 PencilKit \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043c\u043e\u0449\u043d\u044b\u043c\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Vision \u043e\u0442 Apple, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u044e\u0442 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0439 \u0432\u0432\u043e\u0434, \u043d\u043e \u0438 \u0434\u0435\u043b\u0430\u044e\u0442 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0430\u0436\u0443\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0432\u043e\u043b\u0448\u0435\u0431\u043d\u044b\u043c\u0438 \u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u043e\u0442 \u043d\u0438\u0445 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0443\u0441\u0438\u043b\u0438\u0439. Vision \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u044f\u0437\u044b\u043a\u043e\u0432 \u0438 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u044f\u0437\u044b\u043a \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u042d\u0442\u043e\u00a0 \u0435\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0432\u044b\u0448\u0430\u044e\u0442 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044d\u0442\u0438 \u043c\u043e\u0449\u043d\u044b\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 Apple, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u044e\u0442 \u0440\u0430\u0437\u0440\u044b\u0432 \u043c\u0435\u0436\u0434\u0443 \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u0432\u044b\u043c \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u043c \u0432\u0432\u043e\u0434\u043e\u043c \u0438 \u0446\u0438\u0444\u0440\u043e\u0432\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044f \u043d\u043e\u0432\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a, \u0434\u0438\u0430\u0433\u0440\u0430\u043c\u043c \u0438 \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u043d\u0430 iOS \u0438 iPadOS.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f &hellip; <a href=\"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/\">\u0427\u0438\u0442\u0430\u0442\u044c \u0434\u0430\u043b\u0435\u0435 <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":17066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[131,141,144,14,54,132,143],"tags":[145,31,56,140],"class_list":["post-17040","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-gemini-2-5-pro","category-pencilkit","category-swift","category-swiftui","category-132","category-143","tag-pencilkit","tag-swift","tag-swiftui","tag--gemini-2-5-pro"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.8 - aioseo.com -->\n\t<meta name=\"description\" content=\"Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 PencilKit, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u0418\u0442\u0430\u043a, PencilKit -\" \/>\n\t<meta name=\"robots\" content=\"max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n\t<meta name=\"author\" content=\"tatiana.kornilova@gmail.com\"\/>\n\t<meta name=\"keywords\" content=\"vnrecognizetextrequest,pencilkit,vision,\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430,swiftui,swift,pkcanvasview,gemini 2.5 pro,ai,\u0438\u0438\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.8\" \/>\n\t\t<meta property=\"og:locale\" content=\"ru_RU\" \/>\n\t\t<meta property=\"og:site_name\" content=\"\u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. | \u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442 \u043b\u0435\u043a\u0446\u0438\u0439 \u0421\u0442\u044d\u043d\u0444\u043e\u0440\u0434\u0441\u043a\u043e\u0433\u043e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430 &quot; \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439&quot; 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 , 2023,  2024,  2025  \u0438 2026 \u0433\u0433., \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\u043c\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0435\u0439 \u043a\u0443\u0440\u0441\u043e\u0432 \u043a \u043d\u043e\u0432\u044b\u043c \u0432\u0435\u0440\u0441\u0438\u044f\u043c Swift, Objective-C \u0438 iOS.\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. | \u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.\" \/>\n\t\t<meta property=\"og:description\" content=\"Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 PencilKit, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u0418\u0442\u0430\u043a, PencilKit -\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2025-05-31T09:51:33+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2025-10-19T14:51:04+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. | \u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 PencilKit, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u0418\u0442\u0430\u043a, PencilKit -\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#article\",\"name\":\"\\u0424\\u0430\\u043d\\u0442\\u0430\\u0441\\u0442\\u0438\\u0447\\u0435\\u0441\\u043a\\u043e\\u0435 \\u0440\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u0432\\u0430\\u043d\\u0438\\u0435 \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u043e\\u0433\\u043e \\u0442\\u0435\\u043a\\u0441\\u0442\\u0430 \\u0432 \\u0440\\u0435\\u0430\\u043b\\u044c\\u043d\\u043e\\u043c \\u0432\\u0440\\u0435\\u043c\\u0435\\u043d\\u0438 \\u0441 \\u043f\\u043e\\u043c\\u043e\\u0449\\u044c\\u044e Vision, Apple Pencil \\u0438 SwiftUI, \\u043d\\u043e \\u0435\\u0441\\u0442\\u044c \\u043d\\u044e\\u0430\\u043d\\u0441\\u044b. | \\u041e\\u0431\\u0443\\u0447\\u0430\\u044e\\u0449\\u0438\\u0439 \\u043a\\u0443\\u0440\\u0441 \\u043f\\u043e \\u0440\\u0430\\u0437\\u0440\\u0430\\u0431\\u043e\\u0442\\u043a\\u0435 iOS+Swift \\u043f\\u0440\\u0438\\u043b\\u043e\\u0436\\u0435\\u043d\\u0438\\u0439.\",\"headline\":\"\\u0424\\u0430\\u043d\\u0442\\u0430\\u0441\\u0442\\u0438\\u0447\\u0435\\u0441\\u043a\\u043e\\u0435 \\u0440\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u0432\\u0430\\u043d\\u0438\\u0435 \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u043e\\u0433\\u043e \\u0442\\u0435\\u043a\\u0441\\u0442\\u0430 \\u0432 \\u0440\\u0435\\u0430\\u043b\\u044c\\u043d\\u043e\\u043c \\u0432\\u0440\\u0435\\u043c\\u0435\\u043d\\u0438 \\u0441 \\u043f\\u043e\\u043c\\u043e\\u0449\\u044c\\u044e Vision, Apple Pencil \\u0438 SwiftUI, \\u043d\\u043e \\u0435\\u0441\\u0442\\u044c \\u043d\\u044e\\u0430\\u043d\\u0441\\u044b.\\u00a0\",\"author\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/author\\\/tatiana-lornilovagmail-com\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/#person\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/RecognizeTextGemini2_5.gif\",\"width\":362,\"height\":742},\"datePublished\":\"2025-05-31T09:51:33+00:00\",\"dateModified\":\"2025-10-19T14:51:04+00:00\",\"inLanguage\":\"ru-RU\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#webpage\"},\"articleSection\":\"AI, Gemini 2.5 Pro, PencilKit, Swift, SwiftUI, \\u0418\\u0418, \\u0420\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u043d\\u0438\\u0435 \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u043e\\u0433\\u043e \\u0442\\u0435\\u043a\\u0441\\u0442\\u0430, PencilKit, Swift, SwiftUI, \\u0418\\u0418 Gemini 2.5 Pro\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/category\\\/swift\\\/#listItem\",\"name\":\"Swift\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/category\\\/swift\\\/#listItem\",\"position\":2,\"name\":\"Swift\",\"item\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/category\\\/swift\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#listItem\",\"name\":\"\\u0424\\u0430\\u043d\\u0442\\u0430\\u0441\\u0442\\u0438\\u0447\\u0435\\u0441\\u043a\\u043e\\u0435 \\u0440\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u0432\\u0430\\u043d\\u0438\\u0435 \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u043e\\u0433\\u043e \\u0442\\u0435\\u043a\\u0441\\u0442\\u0430 \\u0432 \\u0440\\u0435\\u0430\\u043b\\u044c\\u043d\\u043e\\u043c \\u0432\\u0440\\u0435\\u043c\\u0435\\u043d\\u0438 \\u0441 \\u043f\\u043e\\u043c\\u043e\\u0449\\u044c\\u044e Vision, Apple Pencil \\u0438 SwiftUI, \\u043d\\u043e \\u0435\\u0441\\u0442\\u044c \\u043d\\u044e\\u0430\\u043d\\u0441\\u044b.\\u00a0\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#listItem\",\"position\":3,\"name\":\"\\u0424\\u0430\\u043d\\u0442\\u0430\\u0441\\u0442\\u0438\\u0447\\u0435\\u0441\\u043a\\u043e\\u0435 \\u0440\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u0432\\u0430\\u043d\\u0438\\u0435 \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u043e\\u0433\\u043e \\u0442\\u0435\\u043a\\u0441\\u0442\\u0430 \\u0432 \\u0440\\u0435\\u0430\\u043b\\u044c\\u043d\\u043e\\u043c \\u0432\\u0440\\u0435\\u043c\\u0435\\u043d\\u0438 \\u0441 \\u043f\\u043e\\u043c\\u043e\\u0449\\u044c\\u044e Vision, Apple Pencil \\u0438 SwiftUI, \\u043d\\u043e \\u0435\\u0441\\u0442\\u044c \\u043d\\u044e\\u0430\\u043d\\u0441\\u044b.\\u00a0\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/category\\\/swift\\\/#listItem\",\"name\":\"Swift\"}}]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/#person\",\"name\":\"tatiana.kornilova@gmail.com\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#personImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/33ccc19059014d8a7849c3621afa2b66a5f3e50ac7291c91c30ff35df5747628?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"tatiana.kornilova@gmail.com\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/author\\\/tatiana-lornilovagmail-com\\\/#author\",\"url\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/author\\\/tatiana-lornilovagmail-com\\\/\",\"name\":\"tatiana.kornilova@gmail.com\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/33ccc19059014d8a7849c3621afa2b66a5f3e50ac7291c91c30ff35df5747628?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"tatiana.kornilova@gmail.com\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#webpage\",\"url\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/\",\"name\":\"\\u0424\\u0430\\u043d\\u0442\\u0430\\u0441\\u0442\\u0438\\u0447\\u0435\\u0441\\u043a\\u043e\\u0435 \\u0440\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u0432\\u0430\\u043d\\u0438\\u0435 \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u043e\\u0433\\u043e \\u0442\\u0435\\u043a\\u0441\\u0442\\u0430 \\u0432 \\u0440\\u0435\\u0430\\u043b\\u044c\\u043d\\u043e\\u043c \\u0432\\u0440\\u0435\\u043c\\u0435\\u043d\\u0438 \\u0441 \\u043f\\u043e\\u043c\\u043e\\u0449\\u044c\\u044e Vision, Apple Pencil \\u0438 SwiftUI, \\u043d\\u043e \\u0435\\u0441\\u0442\\u044c \\u043d\\u044e\\u0430\\u043d\\u0441\\u044b. | \\u041e\\u0431\\u0443\\u0447\\u0430\\u044e\\u0449\\u0438\\u0439 \\u043a\\u0443\\u0440\\u0441 \\u043f\\u043e \\u0440\\u0430\\u0437\\u0440\\u0430\\u0431\\u043e\\u0442\\u043a\\u0435 iOS+Swift \\u043f\\u0440\\u0438\\u043b\\u043e\\u0436\\u0435\\u043d\\u0438\\u0439.\",\"description\":\"Apple Pencil \\u043f\\u0440\\u0435\\u0432\\u0440\\u0430\\u0442\\u0438\\u043b iPad \\u0432 \\u043c\\u043e\\u0449\\u043d\\u044b\\u0439 \\u0438\\u043d\\u0441\\u0442\\u0440\\u0443\\u043c\\u0435\\u043d\\u0442 \\u0434\\u043b\\u044f \\u0441\\u043e\\u0437\\u0434\\u0430\\u043d\\u0438\\u044f \\u0437\\u0430\\u043c\\u0435\\u0442\\u043e\\u043a \\u0438 \\u0442\\u0432\\u043e\\u0440\\u0447\\u0435\\u0441\\u043a\\u043e\\u0433\\u043e \\u0441\\u0430\\u043c\\u043e\\u0432\\u044b\\u0440\\u0430\\u0436\\u0435\\u043d\\u0438\\u044f. \\u0410 \\u043a\\u0430\\u043a \\u043d\\u0430\\u0441\\u0447\\u0435\\u0442 \\u043f\\u0440\\u0435\\u0432\\u0440\\u0430\\u0449\\u0435\\u043d\\u0438\\u044f \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u044b\\u0445 \\u043a\\u0430\\u0440\\u0430\\u043a\\u0443\\u043b\\u0435\\u0439 \\u0432 \\u043f\\u0440\\u0438\\u0433\\u043e\\u0434\\u043d\\u044b\\u0439 \\u0434\\u043b\\u044f \\u0438\\u0441\\u043f\\u043e\\u043b\\u044c\\u0437\\u043e\\u0432\\u0430\\u043d\\u0438\\u044f \\u0446\\u0438\\u0444\\u0440\\u043e\\u0432\\u043e\\u0439 \\u0442\\u0435\\u043a\\u0441\\u0442? \\u0414\\u043b\\u044f \\u0440\\u0430\\u0437\\u0440\\u0430\\u0431\\u043e\\u0442\\u0447\\u0438\\u043a\\u043e\\u0432 SwiftUI \\u0444\\u0440\\u0435\\u0439\\u043c\\u0432\\u043e\\u0440\\u043a Vision \\u043e\\u0442 Apple \\u043f\\u0440\\u0435\\u0434\\u043b\\u0430\\u0433\\u0430\\u0435\\u0442 \\u043d\\u0430\\u0434\\u0435\\u0436\\u043d\\u043e\\u0435 \\u0440\\u0435\\u0448\\u0435\\u043d\\u0438\\u0435 \\u043d\\u0430 \\u0443\\u0441\\u0442\\u0440\\u043e\\u0439\\u0441\\u0442\\u0432\\u0435 \\u0434\\u043b\\u044f \\u043e\\u043f\\u0442\\u0438\\u0447\\u0435\\u0441\\u043a\\u043e\\u0433\\u043e \\u0440\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u0432\\u0430\\u043d\\u0438\\u044f \\u0441\\u0438\\u043c\\u0432\\u043e\\u043b\\u043e\\u0432 (OCR), \\u043a\\u043e\\u0442\\u043e\\u0440\\u043e\\u0435 \\u0431\\u0435\\u0441\\u0448\\u043e\\u0432\\u043d\\u043e \\u0438\\u043d\\u0442\\u0435\\u0433\\u0440\\u0438\\u0440\\u0443\\u0435\\u0442\\u0441\\u044f \\u0441 PencilKit, \\u0447\\u0442\\u043e\\u0431\\u044b \\u043e\\u0436\\u0438\\u0432\\u0438\\u0442\\u044c \\u0440\\u0430\\u0441\\u043f\\u043e\\u0437\\u043d\\u0430\\u0432\\u0430\\u043d\\u0438\\u0435 \\u0440\\u0443\\u043a\\u043e\\u043f\\u0438\\u0441\\u043d\\u043e\\u0433\\u043e \\u0432\\u0432\\u043e\\u0434\\u0430. \\u0418\\u0442\\u0430\\u043a, PencilKit -\",\"inLanguage\":\"ru-RU\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/author\\\/tatiana-lornilovagmail-com\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/author\\\/tatiana-lornilovagmail-com\\\/#author\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/RecognizeTextGemini2_5.gif\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#mainImage\",\"width\":362,\"height\":742},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\\\/#mainImage\"},\"datePublished\":\"2025-05-31T09:51:33+00:00\",\"dateModified\":\"2025-10-19T14:51:04+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/#website\",\"url\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/\",\"name\":\"\\u041e\\u0431\\u0443\\u0447\\u0430\\u044e\\u0449\\u0438\\u0439 \\u043a\\u0443\\u0440\\u0441 \\u043f\\u043e \\u0440\\u0430\\u0437\\u0440\\u0430\\u0431\\u043e\\u0442\\u043a\\u0435 iOS+Swift \\u043f\\u0440\\u0438\\u043b\\u043e\\u0436\\u0435\\u043d\\u0438\\u0439.\",\"description\":\"\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \\u043d\\u0435\\u0430\\u0432\\u0442\\u043e\\u0440\\u0438\\u0437\\u043e\\u0432\\u0430\\u043d\\u043d\\u044b\\u0439 \\u043a\\u043e\\u043d\\u0441\\u043f\\u0435\\u043a\\u0442 \\u043b\\u0435\\u043a\\u0446\\u0438\\u0439 \\u0421\\u0442\\u044d\\u043d\\u0444\\u043e\\u0440\\u0434\\u0441\\u043a\\u043e\\u0433\\u043e \\u0443\\u043d\\u0438\\u0432\\u0435\\u0440\\u0441\\u0438\\u0442\\u0435\\u0442\\u0430 \\\" \\u0420\\u0430\\u0437\\u0440\\u0430\\u0431\\u043e\\u0442\\u043a\\u0430 iOS \\u043f\\u0440\\u0438\\u043b\\u043e\\u0436\\u0435\\u043d\\u0438\\u0439\\\" 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 , 2023,  2024,  2025  \\u0438 2026 \\u0433\\u0433., \\u0441\\u043e\\u043f\\u0440\\u043e\\u0432\\u043e\\u0436\\u0434\\u0430\\u0435\\u043c\\u044b\\u0439 \\u0440\\u0435\\u0448\\u0435\\u043d\\u0438\\u044f\\u043c\\u0438 \\u0437\\u0430\\u0434\\u0430\\u043d\\u0438\\u0439 \\u0438 \\u0434\\u043e\\u043f\\u043e\\u043b\\u043d\\u0435\\u043d\\u0438\\u044f\\u043c\\u0438, \\u0441\\u0432\\u044f\\u0437\\u0430\\u043d\\u043d\\u044b\\u043c\\u0438 \\u0441 \\u0430\\u0434\\u0430\\u043f\\u0442\\u0430\\u0446\\u0438\\u0435\\u0439 \\u043a\\u0443\\u0440\\u0441\\u043e\\u0432 \\u043a \\u043d\\u043e\\u0432\\u044b\\u043c \\u0432\\u0435\\u0440\\u0441\\u0438\\u044f\\u043c Swift, Objective-C \\u0438 iOS.\",\"inLanguage\":\"ru-RU\",\"publisher\":{\"@id\":\"https:\\\/\\\/bestkora.com\\\/IosDeveloper\\\/#person\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. | \u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.","description":"Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 PencilKit, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u0418\u0442\u0430\u043a, PencilKit -","canonical_url":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/","robots":"max-snippet:-1, max-image-preview:large, max-video-preview:-1","keywords":"vnrecognizetextrequest,pencilkit,vision,\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430,swiftui,swift,pkcanvasview,gemini 2.5 pro,ai,\u0438\u0438","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#article","name":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. | \u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.","headline":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b.\u00a0","author":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/author\/tatiana-lornilovagmail-com\/#author"},"publisher":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/#person"},"image":{"@type":"ImageObject","url":"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/RecognizeTextGemini2_5.gif","width":362,"height":742},"datePublished":"2025-05-31T09:51:33+00:00","dateModified":"2025-10-19T14:51:04+00:00","inLanguage":"ru-RU","mainEntityOfPage":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#webpage"},"isPartOf":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#webpage"},"articleSection":"AI, Gemini 2.5 Pro, PencilKit, Swift, SwiftUI, \u0418\u0418, \u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, PencilKit, Swift, SwiftUI, \u0418\u0418 Gemini 2.5 Pro"},{"@type":"BreadcrumbList","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/bestkora.com\/IosDeveloper#listItem","position":1,"name":"Home","item":"https:\/\/bestkora.com\/IosDeveloper","nextItem":{"@type":"ListItem","@id":"https:\/\/bestkora.com\/IosDeveloper\/category\/swift\/#listItem","name":"Swift"}},{"@type":"ListItem","@id":"https:\/\/bestkora.com\/IosDeveloper\/category\/swift\/#listItem","position":2,"name":"Swift","item":"https:\/\/bestkora.com\/IosDeveloper\/category\/swift\/","nextItem":{"@type":"ListItem","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#listItem","name":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b.\u00a0"},"previousItem":{"@type":"ListItem","@id":"https:\/\/bestkora.com\/IosDeveloper#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#listItem","position":3,"name":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b.\u00a0","previousItem":{"@type":"ListItem","@id":"https:\/\/bestkora.com\/IosDeveloper\/category\/swift\/#listItem","name":"Swift"}}]},{"@type":"Person","@id":"https:\/\/bestkora.com\/IosDeveloper\/#person","name":"tatiana.kornilova@gmail.com","image":{"@type":"ImageObject","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#personImage","url":"https:\/\/secure.gravatar.com\/avatar\/33ccc19059014d8a7849c3621afa2b66a5f3e50ac7291c91c30ff35df5747628?s=96&d=mm&r=g","width":96,"height":96,"caption":"tatiana.kornilova@gmail.com"}},{"@type":"Person","@id":"https:\/\/bestkora.com\/IosDeveloper\/author\/tatiana-lornilovagmail-com\/#author","url":"https:\/\/bestkora.com\/IosDeveloper\/author\/tatiana-lornilovagmail-com\/","name":"tatiana.kornilova@gmail.com","image":{"@type":"ImageObject","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/33ccc19059014d8a7849c3621afa2b66a5f3e50ac7291c91c30ff35df5747628?s=96&d=mm&r=g","width":96,"height":96,"caption":"tatiana.kornilova@gmail.com"}},{"@type":"WebPage","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#webpage","url":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/","name":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. | \u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.","description":"Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 PencilKit, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u0418\u0442\u0430\u043a, PencilKit -","inLanguage":"ru-RU","isPartOf":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/#website"},"breadcrumb":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#breadcrumblist"},"author":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/author\/tatiana-lornilovagmail-com\/#author"},"creator":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/author\/tatiana-lornilovagmail-com\/#author"},"image":{"@type":"ImageObject","url":"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/RecognizeTextGemini2_5.gif","@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#mainImage","width":362,"height":742},"primaryImageOfPage":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/#mainImage"},"datePublished":"2025-05-31T09:51:33+00:00","dateModified":"2025-10-19T14:51:04+00:00"},{"@type":"WebSite","@id":"https:\/\/bestkora.com\/IosDeveloper\/#website","url":"https:\/\/bestkora.com\/IosDeveloper\/","name":"\u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.","description":"\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442 \u043b\u0435\u043a\u0446\u0438\u0439 \u0421\u0442\u044d\u043d\u0444\u043e\u0440\u0434\u0441\u043a\u043e\u0433\u043e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430 \" \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439\" 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 , 2023,  2024,  2025  \u0438 2026 \u0433\u0433., \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\u043c\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0435\u0439 \u043a\u0443\u0440\u0441\u043e\u0432 \u043a \u043d\u043e\u0432\u044b\u043c \u0432\u0435\u0440\u0441\u0438\u044f\u043c Swift, Objective-C \u0438 iOS.","inLanguage":"ru-RU","publisher":{"@id":"https:\/\/bestkora.com\/IosDeveloper\/#person"}}]},"og:locale":"ru_RU","og:site_name":"\u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. | \u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442 \u043b\u0435\u043a\u0446\u0438\u0439 \u0421\u0442\u044d\u043d\u0444\u043e\u0440\u0434\u0441\u043a\u043e\u0433\u043e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442\u0430 &quot; \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439&quot; 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 , 2023,  2024,  2025  \u0438 2026 \u0433\u0433., \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\u043c\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0435\u0439 \u043a\u0443\u0440\u0441\u043e\u0432 \u043a \u043d\u043e\u0432\u044b\u043c \u0432\u0435\u0440\u0441\u0438\u044f\u043c Swift, Objective-C \u0438 iOS.","og:type":"article","og:title":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. | \u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.","og:description":"Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 PencilKit, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u0418\u0442\u0430\u043a, PencilKit -","og:url":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/","article:published_time":"2025-05-31T09:51:33+00:00","article:modified_time":"2025-10-19T14:51:04+00:00","twitter:card":"summary","twitter:title":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. | \u041e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0443\u0440\u0441 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 iOS+Swift \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.","twitter:description":"Apple Pencil \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b iPad \u0432 \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u0442\u043e\u043a \u0438 \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0410 \u043a\u0430\u043a \u043d\u0430\u0441\u0447\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u044b\u0445 \u043a\u0430\u0440\u0430\u043a\u0443\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0439 \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0442\u0435\u043a\u0441\u0442? \u0414\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 SwiftUI \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Vision \u043e\u0442 Apple \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (OCR), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0435\u0441\u0448\u043e\u0432\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 PencilKit, \u0447\u0442\u043e\u0431\u044b \u043e\u0436\u0438\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430. \u0418\u0442\u0430\u043a, PencilKit -"},"aioseo_meta_data":{"post_id":"17040","title":null,"description":null,"keywords":[{"label":"VNRecognizeTextRequest","value":"VNRecognizeTextRequest"},{"label":"PencilKit","value":"PencilKit"},{"label":"Vision","value":"Vision"},{"label":"\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430","value":"\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430"},{"label":"SwiftUI","value":"SwiftUI"},{"label":"Swift","value":"Swift"},{"label":"PKCanvasView","value":"PKCanvasView"},{"label":"Gemini 2.5 Pro","value":"Gemini 2.5 Pro"},{"label":"AI","value":"AI"},{"label":"\u0418\u0418","value":"\u0418\u0418"}],"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":{"faqs":[],"keyPoints":[],"titles":[],"descriptions":[],"socialPosts":{"email":[],"linkedin":[],"twitter":[],"facebook":[],"instagram":[]}},"created":"2025-05-31 09:49:50","updated":"2026-02-22 20:12:56","seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/bestkora.com\/IosDeveloper\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/bestkora.com\/IosDeveloper\/category\/swift\/\" title=\"Swift\">Swift<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b. \n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/bestkora.com\/IosDeveloper"},{"label":"Swift","link":"https:\/\/bestkora.com\/IosDeveloper\/category\/swift\/"},{"label":"\u0424\u0430\u043d\u0442\u0430\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u043a\u043e\u043f\u0438\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Vision, Apple Pencil \u0438 SwiftUI, \u043d\u043e \u0435\u0441\u0442\u044c \u043d\u044e\u0430\u043d\u0441\u044b.\u00a0","link":"https:\/\/bestkora.com\/IosDeveloper\/%d1%84%d0%b0%d0%bd%d1%82%d0%b0%d1%81%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%be%d0%b5-%d1%80%d0%b0%d1%81%d0%bf%d0%be%d0%b7%d0%bd%d0%b0%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%80%d1%83%d0%ba%d0%be%d0%bf%d0%b8\/"}],"jetpack_featured_media_url":"https:\/\/bestkora.com\/IosDeveloper\/wp-content\/uploads\/2025\/05\/RecognizeTextGemini2_5.gif","_links":{"self":[{"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/posts\/17040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/comments?post=17040"}],"version-history":[{"count":4,"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/posts\/17040\/revisions"}],"predecessor-version":[{"id":17213,"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/posts\/17040\/revisions\/17213"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/media\/17066"}],"wp:attachment":[{"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/media?parent=17040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/categories?post=17040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bestkora.com\/IosDeveloper\/wp-json\/wp\/v2\/tags?post=17040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}