
translatesAutoresizingMaskIntoConstraints של הילד, מבצעת addChild ו-didMove(toParent:), ומוסיפה את ה-view עם אילוצים לשמאל, לימין, לתחתית ולגובה.initVC טוענת את הדיאלוג מהסטוריבורד לפי ה-storyboard identifier, ועושה cast ל-BottomViewController.state נשאר read-only מבחוץ.UIViewPropertyAnimator עם קפיץ (duration 0.4 ו-damping 0.7). ב-completion נשמר המצב החדש והאנימטור משתחרר. משתמשים ב-weak self כדי לא ליצור memory leak.mask corners מוגבל לפינות העליונות בלבד, כך שהחלק התחתון לא מעוגל.layoutIfNeeded על ה-superview כדי שהאנימציה תתבצע.הטקסט המלא של הדקות הראשונות בהרצאה «אנימציה ב-Xcode-Swift - חלק 6» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
שלום וברוכים הבאים, אנחנו רוצים להמשיך עם ה-View Property Animator Scrabbing שהתחלנו בשיעור שעבר, אבל הפעם ליישם את זה על חלק יותר ממשי ומציאותי אני אפתח פה שנייה את האפליקציה של המפות כדי להראות לכם איזשהו סגנון של דיאלוג אתם רואים יש לי פה את הדיאלוג הזה שקופץ באפליקציה של המפות שהוא אינטראקטיבי, אני יכול לעשות סווייפ
למטה כדי להוריד אותו וסווייפ למעלה עם האצבע כדי להעלות את הדיאלוג הזה ואנחנו רוצים ליצור משהו בסגנון הזה, אוקיי?
של Bottom Sheet Dialog, ככה אנחנו קוראים לזה. אז בואו ננסה לראות איך אנחנו עושים את זה. אנחנו נפתח פה פרויקט חדש ב-Xcode, זה יהיה Single Vue Application.
אנחנו נרצה כמובן לתת שם לפרויקט, אז בואו נקרא לפרויקט שלנו Vue Property Scrubbing ונוסיף את המילים Bottom Sheet. נשים לב פה שכל ה-Default זה Language Swift ו-User Interface Storyboard, ונעשה Next.
עכשיו, כדי להתחיל, אנחנו בעצם נרצה לא לעבוד פה ב-Main Storyboard. כאן אנחנו נרצה הרי להכניס את זה אבל אנחנו נרצה לייצר לעצמנו פופ-אפ סטורי בורד כמו שעשינו בשיעורים קודמים אז בואו נייצר אחד אני אעשה ניו פייל סטורי בורד ואנחנו נקרא לזה פופ-אפ סטורי בורד הסיבה שאנחנו רוצים להפריד את זה לסטורי בורד נפרד זה כדי שהפרויקט שלנו
יהיה יותר מודולרי ויותר מסודר ויותר בר תחזוקה בסטורי בורד החדש אנחנו רוצים להוסיף view קונטרולר כדי לעבוד אז אני אלחץ פה על הפלוס בצד ימין ואני אוסיף קודם כל view קונטרולר וזה בעצם יהיה הדיאלוג שקופץ אוקיי אז כדי לעצב אותו קצת בואו נלך נגיד לאסט ונוסיף תמונה אני אפתח את אייקון סייט בשביל למצוא איזושהי תמונה אני אקח תמונה של לב בסדר אז
זו התמונה שבחרתי אתם כמובן מוזמנות ומוזמנים לבחור איזה תמונה שאתם רוצים ובחזרה לסטורי בורד אנחנו רוצים לשים פה את התמונה שלנו אז אימג' ויו בחיפוש ואני גורר לכאן אימג' ויו ואנחנו כמובן נבחר את התמונה שלנו שעכשיו הבאנו אז התמונה הזאת ואני אקטין את זה מעט ולייבל אני אוסיף בשביל איזשהו טקסט כותרת על הלייבל
אני ארצה לעשות דברים שוליים כמו לשנות קצת את הפונט וכאלה אז אני לוחץ פה על הפונט משנה מ-system font ל-custom font ובוא ניקח פה ב-family סליחה מרקר פלט נניח ואנחנו נרצה גם להגדיל את הפונט לגודל יותר גדול ואישור עכשיו בטקסט של הלייבל אנחנו נרצה לרשום נניח please tell us what you think אוקיי
עכשיו אנחנו רואים שזה קצת ארוך מדי, בואו ננסה לעשות אילוצים ונתמודד עם העניין הזה. כדי להתמודד עם העניין הזה, קודם כל אני אגדיר ש-number of lines פה יכול להיות אפילו 3 בלייבל.
זאת אומרת שהלייבל יכול לעשות טרופינג לשלוש שורות. הוא לא יעשה את זה אוטומטית ואנחנו נצטרך לעבוד, אבל בשביל זה אנחנו פה. עכשיו מבחינת אילוצים, אני אתפוס את ה-image view קודם כל, ואני אצמיד אותו לצד שמאל, אוקיי? אז שמאלה וגם למעלה, ובואו ניקח איזה שהם שוליים דיפולטיים של 16 מלמעלה ו-16 משמאל ונעשה פה אישור.
אז הנה הלב שלי כבר במקום. אתם רואים מה הבעיה עם הלייבל? יש פה יותר מדי טקסט, נכון? ואפילו אם אני אגדיל פה עוד יותר את הפונט אז יראו את הבעיה הזאת עוד יותר.
זה לא בעיה, זה מה שאנחנו יודעים להסתדר איתו. מבחינת אילוצים של הלייבל, אז קודם כל אני אכניס אותו בכל זאת למסך כדי שיהיה לי באמת אפשרות לעשות את האילוצים נכון.
וברגע שזה נמצא בפנים אני אלך על האילוצים פה ואני אעשה אילוצים אותו דבר של 16 מלמעלה ו-16 מימין הפעם ואני רוצה גם 16 משמאל ה-16 הוא כמובן משמאל ל-image view ואפשר לראות את זה כאן בדיקה של על מה אני עושה את האילוץ אני אעשה add constraints עכשיו יש לנו בעיה זאת אומרת אנחנו מדברים פה על מי לוקח את המקום שמיותר או מי מתכווץ ומי מתרחב כלומר priorities
של constraints נכון? אז כדי לטפל בפיוריטיס אנחנו הולכים פה לסרגל ובסרגל אנחנו רוצים לתפוס את הנניח לייבל ולהגיד ללייבל שמבחינת כמה הוא רוצה לחבק אז הוא לא רוצה לחבק בכלל הוא רוצה ככה לגדול אם אפשר וזה פותר לי פה את הבעיה הזאת אבל בוא נגיד אם אין מקום אז אנחנו נגיד שהוא גם לא מתנגד להתכווץ בסדר אז שתי הדברים האלה ככה
מבחינה אופקית יכולים לסגור לי פה את העניין הזה טוב אני לא רוצה שהטקסט יתמרכז אז אני רוצה ככה להזיז אותו לפה זה נראה לי יותר חינני והנה העיצוב של הדיאלוג שלנו כמובן שכל היופי זה שהדבר הזה יקפוץ נכון זאת אומרת זה סתם כרגע איזשהו עיצוב ולא עושים עדיין משהו מעבר בשביל לסיים את הדבר הזה אנחנו נרצה לעשות שתי דברים א׳ אני רוצה לתת
לזה סטורי בורד אידנטיפייר כדי שאני אוכל להתחל את זה אחר כך מהקוד אז בוא נקרא לזה נניח פופאפ אני אזכור את השם הזה או שאני אתיק אותו אחר כך אפשר לקרוא לו בטום גם אם אתם רוצים עכשיו עכשיו יותר מזה אנחנו גם רוצים לעשות פה קליק ימני new file ולייצר לזה view controller אוקיי אז אנחנו עושים
new file הפעם cocotouch class והטיפוס הוא ua view controller ובוא נקרא לזה bottom view controller יפה אז יש לי קלאס אבל אני כמובן צריך לקשר אותו נכון אז לא רק לתת storyboard id אלא גם לתת לפה את הקלאס שעכשיו יצרנו מעולה אז הנה יש לי פה את הפופאפ אבל איך אני מכניס אותו פנימה נכון זאת אומרת הנה view קונטרולר אני רוצה להכניס אותו נניח למיין
או לויו קונטרולר אחר. כעיקרון עשינו בעבר אמבד, עשינו אמבד סגווי אם אתם זוכרים בפרויקט של האנימציות. אז היום אנחנו רוצים לעשות בדיוק את אותו אמבד סגווי אבל הפעם מהקוד כדי שתוכלו ללמוד גם לעשות את הדבר הזה.
וזה עוד יותר יפה כי זה יותר מודולרי. כדי לעשות את האמבדינג בעצם אנחנו נייצר עוד קלאסט נוסף שהוא יהיה יוטיל כזה שעוזר לנו לעשות אמבד מהר. אמבד הכוונה להכניס view controller ולא סתם שאנחנו נכניס את ה-view controller אלא אנחנו נכניס אותו מלמטה כמו שאתם עוד מעט תראו אז אחרי הקדמה קליק ימני New File, Cocoa Touch Class או אפילו Swift File בגלל
שאנחנו לא באמת רוצים פה לייצר קלאס אז אני אקרא לזה UI View Controller + Extensions כלומר אני רוצה לייצר הרחבה לכל ה-View קונטרולרים כדי שכולם ידעו לעשות את האמבד הזה של Bottom Sheet מלמטה. כאן כמובן צריך להיות אימפורט ל-UI Kit ואנחנו נרצה לעשות extension ל-UI view controller כמו שאמרנו, אז extension ל-UI view controller יפה אז זה הקובץ שלנו.
עכשיו פה בקובץ מה אנחנו בעצם רוצים לעשות? אנחנו רוצים להוסיף פעולה אז בוא נוסיף function והפעולה הזאת בעצם תעשה לנו אמבד אז בוא נקרא לה bottom אמבד כדי שיהיה מה לעשות לו אמבד אנחנו נרצה כפרמטר בוא נסגור את זה שנייה נהיה אנחנו נרצה כפרמטר לקבל view controller שעליו אנחנו רוצים לעשות את האמבד אז UI view קונטרולר אחר ואנחנו נרצה לקבל שוליים insights נקרא לזה
מרג'ינס אם אתם רוצים בשפת אחרות והטיפוס של זה בסוויפט זה UI Edge Insets כלומר לעשות אמבד אבל אם אומרים לי עם איזה שם שוליים אז בכיף אני אוסיף שוליים גם.
טוב בואו נזכר בקונטיינר בעצם שעשינו אז בעצם view קונטרולר מארח view קונטרולר אחר כש-view קונטרולר מארח view קונטרולר אחר הוא בראש ובראשונה מארח את ה-view שלו ל-view קונטרולר הזה יש לו גם view כמו שלכל view
קונטרולר יש view אז השלב הראשון שאני עושה כאן זה אני אומר לוויו של הוויו קונטרולר שאני רוצה לארח שלא יעשה אילוצים בסדר אז בוא נגיד לו translate masks into constraints false אוקיי אז זה הדבר הראשון אני אומר לו אל תעשה אילוצים don't use auto constraints אנחנו נעשה אותם בעצמנו זה הוויו של הוויו קונטרולר שאנחנו
רוצים לארח עכשיו אנחנו רוצים להוסיף אותו אז בואו נוסיף אותו אז במקום לעשות embed segue אנחנו עושים add child ל-view-controller ומוסיפים את ה-child, אוקיי?
זה בעצם ה-embed כ-view-controller, ואנחנו יכולים גם לספר לו שאנחנו מעבירים אותו ל-view-controller, tell the view-controller it's about to be used.
זה חלק מהלייפסייקל של view-controllers, בואו נרשום את זה ואז אתם תוכלו לראות. אז אנחנו נודיע לו child.did move to parent, אוקיי? ש-parent זה אנחנו, אז אנחנו יכולים להגיד self.
אנחנו בעצם נותנים לו מידע בלייפסייקל, כמו שיש view-did-appear, view did load וכן הלאה אז עכשיו אמרנו לו view controller did move to parent אוקיי הלאה אנחנו הכנסנו אותו ואנחנו צריכים לתת לו אילוצים נכון זאת אומרת ואנחנו נרצה גם להכניס את הview שלו אז בואו נכניס את הview שלו קודם כל אולי נעשה את זה אפילו פה אז self.view add subview ל child.view אז בעצם עכשיו הוספנו אותו ויכלו לראות אותו אבל אין
לו אילוצים וזה בדיוק השלב הבא שלנו אז מבחינת אילוצים בואו נייצר פשוט מערך של אילוצים let constraints שווה למערך ופה בתוך המערך אנחנו רוצים להתחיל לייצר אילוצים אז child.view.leading anchor leading זה כמו להגיד שמאלה נכון אז את זה אנחנו רוצים לאלץ equal to עם קונסטנט אוקיי ו-equal to ה-view
שלנו נקודה safe area layout guide.leading anchor ומבחינת קונסטנט אז אנחנו נשתמש באינסיטים שנתנו לנו אוקיי אז אז insights.left הקונסטנס זה בעצם המרג'ינס לשוליים האינסטים יפה אז זה אילוץ אחד שמאלה אנחנו בעצם אומרים left to left אז בוא נוסיף עוד אילוץ מקביל של right to right העתקתי את השורה הזאת ואני מדביק
במקום leading anchor אני אשנה פשוט לטריילינג וtrailing to the right אז קודם כל נשתמש באינסט של הרייט וגם כאן לטריילינג anchor אז הנה יש לי אילוץ שמאלה אילוץ ימינה מה חסר לנו נרצה להדליץ גם את החלק התחתי אוקיי אז בוא נוסיף את זה גם כן child.bottomNcore.vue.bottomNcore.
constraint = 2 אפשר לרשום סלף אפשר לא לרשום סלף נכון? view.bottomNcore ומבחינת קונסטנט האמת היא שאני רוצה להעביר פה 0 אבל בוא נעביר את הinsense.bottom אולי מי שרוצה לתת לנו משהו אחר אוקיי ודבר אחרון אנחנו צריכים לקבוע גובה לדבר הזה כי בעצם הצמדנו אותו לשמאל הצמדנו אותו לימין הצמדנו אותו לחלק התחתון אבל מהי הגובה של
הbottom sheet? זה האילוץ הכי משמעותי כאן בפרויקט, אז בואו נוסיף אותו, child.view.height.constraint, נעשה לו constraint, equal to, ופה אנחנו לוקחים קונסטנט, אז הקונסטנט שלנו זה insets.top פשוט, אז אנחנו לא צריכים את כל זה, יש את equal to constant במקום, בסדר, אז רגע.
אוקיי, וזה בעצם הגובה שהוא יקבל מאיתנו. עכשיו, כל האילוצים האלה הם חסרי תועלת בעצם, כי לא הכתבנו אותם, אז בואו נכתב את ה-constraints, אז יש לנו את הפעולה NSLayoutConstant.activate שמקבלת מערך של אילוצים ואני אתן לה את המערך של האילוצים שלי, יפה?
אז עכשיו כל האילוצים מאוכתבים ובעצם אנחנו יכולים להשתמש בזה. עוד משהו קטן, אנחנו רוצים קצת יותר ללמוד על אילוצים אפילו ממה שלמדנו עד כה כי למדנו להוסיף אילוצים אבל אנחנו רוצים גם לדעת לזהות אילוצים.
לאילוצים אפשר לתת Identifier כדי לזהות אותם, אז בואו נלמד את זה, תחשבו על זה כהשערה כי אנחנו לא חייבים את זה פה בפרויקט אבל כדאי ללמוד, נכון?
אז better knowledge of constraints from code אפשר לקחת נגיד את האילוצים constraints.last אז מי זה בעצם? זה ה-height anchor ואני יכול לתת לו identifier אוקיי?
כלומר כל אילוץ שאני מוסיף אני יכול לתת לו identifier וככה אני אוכל לזהות אותו יותר מאוחר אוקיי? בוא נקרא לו נגיד height layout או משהו. אז זה שלב אחד, אתם רוצים בעצם לדעת לזהות אילוץ אחר כך אז אפשר לתת לו את ה-identifier.
דבר שני, נניח שמישהו שואל אתכם, טוב, איפה האילוץ הזה עם ה-ID שנתתי, עם ה-Identifier? אז אם אתם רוצים למצוא אותו, בואו נגדיר איזשהו משתנה, נגיד Height Constraint, זו תהיה תכונה מחושבת מסוג של NSליout Constraint Optional, בגלל שאולי אנחנו לא נמצא אותו, וכאן אנחנו פשוט יכולים למצוא את כל האילוצים
של ה-View שלנו, Self.View.Constraints, ואנחנו רוצים לעשות לזה בעצם פילטר, אז אנחנו אומרים First Wear, השלמתי פה את ה-Closure הזה,