
הטקסט המלא של הדקות הראשונות בהרצאה «אנימציה ב-Xcode-Swift - חלק 3» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
שלום וברוכים הבאים בשיעור הקודם ראינו איך אנחנו יכולים להציג קולקשן ויו כאמבדד ויו קונטרולר, כלומר להציג ויו קונטרולר אחד בתוך ויו קונטרולר שני.
היום אנחנו נרצה קודם כל ללמוד איך לבצע את התקשורת הזאת בצורה מסודרת שהיא מקובלת גם בעולם, ודבר שני, מעבר לביצוע של התקשורת בין שתי ויו קונטרולרים, בין השיחה הזאת בין שני הויו קונטרולרים, הדבר השני שאני רוצה לעשות זה קצת אנימציות ולשדרג את הידע שלנו באנימציות אז מה שאנחנו נעשה, אנחנו קודם כל נתחיל ב-Collection
View Controller ב-Collection View Controller אנחנו בעצם רוצים לקיים איזשהו דיאלוג כדי לקיים דיאלוג בתכנות מונחת סמים, הרבה פעמים אנחנו הולכים לפתרון של callback באיזושהי צורה. עכשיו, מה שאנחנו יכולים לעשות זה להגדיר בקובץ שלנו מה שנקרא delegate.
בואו קודם כל אני אגדיר את זה ואז נוכל לראות. אני מגדיר פרוטוקול פרוטוקול זה בעצם רשימה של מתודות בסדר הוא מגדיר סט של מתודות סט של התנהגויות אז נקרא לפרוטוקול שלנו אייקונס קולקשן ויו קונטרולר דלגייט ככה נקרא לו אייקונס קולקשן ויו
קונטרולר דלגייט עכשיו הדלגייט בעצם זו דרך להודיע הודעות כן להפעיל פעולות ואת הפעולות רושמים כאן בסדר נגיד יש לי פרוטוקול פרוטוקול זה רשימה של פעולות באיזושהי צורה. אז בואו נגדיר לעצמנו פעולה, נניח נקרא לה did select, נגיד אייקון, עכשיו האייקון יהיה טייפ של UI image, אנחנו רוצים שהדבר הזה יהיה פונקציה, סליחה.
יפה, אז did select icon למשל. פרמטר נוסף שאנחנו נרצה יהיה ה-position, אז אני אקרא לפרמטר הזה add שם חיצוני, position שם פנימי, והטייפ של זה יהיה city point.
עצרו רגע, בואו נראה מה כתבנו. אז בעצם יש לי פרוטוקול שאמור להודיע למי שמעוניין שלחצו על אייקון בפוזיצ'ן מסוים, ב-XY מסוים.
עד כאן זה פשוט ליסט של definitions, בסדר? ליסט של behaviors. ויש לי כאן רק one behavior, one method did select.
איך אנחנו משתמשים בדבר הזה בכלל? אנחנו נראה, לאט לאט. הדבר הזה בעצם נקרא delegation, אוקיי? delegate, delegation זה design pattern שקצת קשה לעכל אותו, קצת קשה ככה לתפוס אותו בהתחלה כי הוא בנוי על אוסף של סדרה של פעולות אבל הצעד הראשון הוא להגדיר את הפרוטוקול.
אז הנה, עשינו את הצעד הראשון. עכשיו, הצעד השני זה לקרוא לפעולה הזאת של דלגייט ולשמור משתנה מסוג הדלגייט. מה הכוונה? יהיה לנו פה אופצ'יונל var תרשמו לעצמכם צעד שני במתכון מטבח, נקרא לו דלגייט והטייפ שלו יהיה הטיפוס שהגדרנו למטה.
אז Icons Collection View Delגate. אוקיי אופציונל למה אופציונל כי אם יהיה לנו מאזין אז מצוין אם לא יהיה לנו מאזין אז אנחנו גם נעבוד אוקיי כלומר הדבר הזה הוא סטנדלון קולקשן ויו הוא קונטרולר שלי הוא סטנדלון הוא יכול לעבוד יכול לא לעבוד
עכשיו אם מישהו רוצה להירשם לאיבנט הזה שנקרא did select icon מי שרוצה לדעת שלחצו על אייקון אז הוא יכול להירשם אבל זה לא הכרחי זה לא חובה עכשיו מה שאנחנו נעשה יש לנו פה פעולה בקולקשן ויו שנקראת did select item at אוקיי היא לא כתובה פה באוסף המרשים של העיירות מלמטה אני אוריד
דרך אגב את כל העיירות אני לא צריך אותן למרות שזה נחמד כמובן לקרוא אותן אני רוצה לדרוס פה פעולה שנקראת did select item at זאת פעולה שממילא הייתה כאן אוקיי כלומר תמיד יכולתי לקבל מידע על לחיצות ב-collection view עכשיו מה אני רוצה לעשות ב-did select item at קודם כל אנחנו רוצים לדעת על איזה
תמונה לחצו אז let שווה לאיקונס במקום האינדקס פאף ואנחנו יודעים את הסיפור הזה עם המודול הוא נכון אז יש לי תמונה ביד אוקיי אינדקס פאף נקודה אייטם מוד 6 אז הנה מצאתי את האימג' האימג' זה אחת התמונות שאנחנו מציגים עליה לחצו יפה מאוד
מכאן אני בעצם יכול להגיד הנה did select image אבל מה ה-position של הדבר הזה מה ה-XY של הדבר הזה באופן נאיבי יש לנו פעולה שנקראת layout attributes אני אראה לכם אותה. אז הייתי יכול לומר let point שווה ל-collection view נקודה layout attributes for item את אינדקס פאף.
האינדקס פאף זה נתון לי כבר, אז הנה יש לי את ה-layout attributes. מתוך ה-layout attributes יש לנו את ה-center למשל.
אוקיי? עכשיו זה cg-point. זה אופציונל בגלל שלא בהכרח שיהיה להם layout attributes עבור, אז בואו נעשה נניח guard let, אחרת יצא החוצה.
והנה יש לי גם image וגם point. אני שוב פעם טוען שזה פתרון נאיבי, אני אראה לכם פתרון יותר מושלם אחר כך אבל בינתיים אנחנו נתחיל, זו התחלה טובה דרך אגב וזה הכיוון אבל הוא לא מושלם אני אראה לכם אחר כך למה ואיך לתקן.
עכשיו הדלגייל דיזיין פאטרן זה הדבר הכי חשוב שאני יכול ללמד אתכם וזו שאלה ששואלים ברעיונות עבודה לפעמים וגם אם לא שואלים אז אתם חייבים לדעת את זה בשביל לעשות איזושהי עבודה בתכנון.
אז כדאי ככה לשבת טוב טוב טוב טוב על הדבר הזה כל השלבים איך זה עובד מגדירים פרוטוקול רצוי אפילו שהפרוטוקול הזה יהיה פרוטוקול שמיועד לקלאסים בלבד ולא לשום דבר אחר אז אני ארשום שאני באונד רק לקלאסים הפרוטוקול הזה מיועד לקלאסים בלבד מי שיכול לממש את הפרוטוקול יהיה קלאס בלבד לא אינאמים ולא סטרקטים זה לא סתם פרוטוקול זה קלאס פרוטוקול
כלומר פרוטוקול שמיועד לקלאסים עכשיו למה זה טוב בגלל שעכשיו אני יכול להחזיק משתנה מסוג ה-Delegate ולהפוך אותו להיות Weak Variable. Weak מתייחס בעצם ל-Reference Counting נכון לספירה של מצביעים ומה שאני רוצה להגיד פה בעצם זה שתחשבו שיש לכם שתי קלאסים שמדברים אחד עם השני אם קלאס A מצביע על קלאס B
וקלאס B מצביע על קלאס A עלול להיווצר לנו מצב של Retained Cycle מצב שבו אובייקט אחד מצביע על השני והשני מצביע עליו ואז שניהם ביחד יש להם רפרנס קאונט של יותר מאחד והם לא יכולים להיאסף הזיכרון שלהם לא יכול להיאסף אפילו אם בעצם משתמש לנו בכלל עבר מסך יש לנו נוצר לנו ממורי ליק בגלל שהם מצביעים אחד על השני
כדי למנוע ריטיין סייקל אנחנו נחזיק וויק רפרנס באחד הצדדים אוקיי נגיד כאן אנחנו נחזיק וויק רפרנס ואז אנחנו לא מחזיקים רפרנס חזק אחד הצדדים מצביע בצורה חזקה והצד השני מצביע בצורה חלשה, בצורה שיוויק, אוקיי?
אז זהו, אז שלב מספר 2, הגדרנו רפרנס או וויק רפרנס מהטייפ של הדלגייט, ושלב מספר 3, אנחנו רוצים להודיע לדלגייט ברגע שקרה איזשהו איבנט מעניין.
האיבנט המעניין did select item פה, אז אנחנו פשוט רוצים להודיע לדלגייט, אנחנו יכולים להגיד the delegate, עכשיו אתם יודעים שהוא אופציונל אז אם אתה קיים, בחרו באייקון, אני רציתי להודיע לך על זה, יקירי.
אז הנה, קח לך את האימג', והפוינט, אני אתן לך את הפוינט הנוכחי שאני חושב שהוא נאיבי כמו שאמרנו, אבל מצוין. שימו לב לכל השלבים כמעט יחד.
הגדרנו פרוטוקול, הגדרנו רפרנס לפרוטוקול, ואם הוא קיים, אז ברגע שקורה איבנט שאנחנו רוצים להודיע עליו, אז אנחנו מפעילים את האיבנט.
call the delegate זה כמו callback, אז כתבתי call, אתם יודעים, tell the delegate, talk to the delegate, בסדר? להודיע, inform.
עכשיו, זה צד אחד. צד שני זה ה-view controller. עכשיו, הוא רוצה לדעת בעצם, אוקיי? אני אמזער פה קצת את הדברים האלה, אני אוריד מפה קצת הערות ואני אסדר קצת את הקוד כדי לפנות לנו מקום.
בסדר? אנחנו כבר פחות מתעניינים בפונקציה הזאת. הנה, יש לנו פה, זה שייך שוב פעם לקודם, אנחנו פחות מתעניינים, אבל אני אשאיר את זה בפרויקט.
עכשיו, מה שאנחנו רוצים עכשיו להוסיף, זה בעצם להירשם כמאזין. אני רוצה להגיד ל-ViewController הזה שאני מציג, לאייקונים, שאם בחצו על אלמנט, תודיע לי.
כדי לעשות את זה, אנחנו קודם כל נצטרך להשיג רפרנס לאלמנט. למזלנו, יש לנו את ה-Child View Controlers. הוא בעצם נחשב כ-Child שלי, הוא Children, הוא נמצא ב-Children.
אנחנו יכולים ממש ככה לבדוק כמו קודם. ניקח את ה-Children הראשון, נקרא לזה דולר אפס כמו שעשינו קודם רגע אני אצמצם פה קצת דולר אפס is הטייפ ששם נכון?
אייקונס קולקשן ויו קונטרולר אוקיי וזה בעצם בוא נעשה let icons vc שווה עכשיו אנחנו יודעים שזה יהיה האייקונס ויו קונטרולר אז אני אעשה קאסטינג ואם יש לי אותו if let אייקונס vc שווה לאייקונס vc אם הוא לא נעיל אזי דרך אגב לא בכוונה האותיות שונות אני יכול לבחור באותן אותיות הכל טוב אין שום בעיה מצוין אזי אנחנו רוצים להגיד
לאייקונס vc שברגע שיש לו דברים מעניינים אני רוצה לדעת מזה אני רוצה לקבל אינפורמציה מתי שלחצו אצלו על אייקון זאת התקשורת אני רוצה להירשם כמאזין לאיבנט אוקיי אז מה שאני רוצה אני רוצה להיות הדלגייט אז כדי להיות הדלגייט אני ארשום פה נקודה שווה לסלף.
יש פה קצת בעיה כי אתה רוצה להיות הדלגייט? אין שום בעיה, רק תוסיף אותה מתודה שכתובה בפרוטוקול. אנחנו לא רוצים לעשות קאסטינג בפורס, אנחנו רוצים פשוט באמת לממש את הפרוטוקול וזה הצעד הבא.
הצעד הבא יהיה באמת לממש את הפרוטוקול extension ל-view controller שאני נמצא בו כדי לממש את הדלגייט ואם מימשנו את הדלגייט אז חייב שתהיה לנו את הפעולה של did select item add נכון did select icon add מצוין מה אני אעשה פה זה כבר עניין שלי אולי אני אדפיס את האייקון אולי אני אדפיס את הפוזישן לרגע לעת עתה אבל בואו נצליח בואו נבדוק אם הצלחנו במשימה
שלנו עד הלום בוא נראה מה קורה פה בעצם אז אנחנו מריצים אני לוחץ על האייקון של הליצן רואה שזו איזושהי תמונה ויש פה איזשהו פוזישן אני לוחץ על הצען השני תמונה אחרת עם פוזישן אחרת, אתם רואים פה כתובת קצת שונה בזיכרון, לא בהרבה, אבל כן קצת שונה.
מצוין, ואנחנו רואים גם שהפוזישן התקדם בציר X, ציר Y באותו גובה, אז 75, אבל ציר X מתקדם יפה, רואים? נגיד השמש, 300. הדבר הזה, 422. מעניין.
עכשיו, מה שפחות מוצלח מבחינתנו זה שהבטיח הוא ב-500 כביכול, וזה איקס הולך ועולה ולכן אמרתי קודם שהפוזישן הוא קצת נאיבי אבל היי לאט לאט צעד צעד שימו לב שהצלחנו לקבל פה לויו קונטרולר המארח אינפורמציה
מהצ'יילד ויו קונטרולר והתקשורת הזאת בין ויו קונטרולרים היא נושא מאוד מאוד חשוב וחשוב לי מאוד שתלמדו אותו הדלגייט דיזיין פאטרן אוקיי אז תנסו לעצור פה את הסרטון לעשות לעצמכם את כל האישור קו שאתם רוצים לפני שאנחנו מתקדמים קדימה.
בסדר? זאת אומרת לשבת פה, לעבוד, לעשות את אותה דוגמא מצידי כמו תוכי אלף פעמים עם עוד פרויקט ועוד פרויקט עד שאתם יוצאים ומבינים את זה. לקרוא באינטרנט מה שאתם צריכים, לחזור על הסרטון, להכיר היטב את הדלגייט פאטר ולכתוב אותו בעצמנו, לא רק לצרוך אותו כמו שאנחנו עושים הרבה פעמים
ב-Table View Controller או ב-Collection View Controller. טוב, בסדר, אז אמרתי לכם מספיק מה אני חושב. מה שאנחנו רוצים עכשיו לעשות זה קצת אנימציות, אז בואו נעשה אנימציה.
אנחנו רוצים בעצם לעשות UIView אנימאט, ובואו נתחיל בזה שכבר את זאת עשינו, נכון? אנימאט וויב דיוריישן כבר עשינו עם טיים אינטרוויל, בסדר? יש פה עוד אחת שמקבלת קומפלישן.
קומפלישן זה איזשהו קטע קוד שאני רוצה לעשות ברגע שסיימתי את האנימציה. בואו נראה לכם מה הכוונה. אז אנחנו רוצים לעשות uofu animate with duration בוא נגיד duration יהיה 0.4 אנימציות זה בלוק אז עושים פה enter בסדר ואני אעשה פה רגע הערה לגבי הקוד עכשיו completion זה גם כן בלוק אז שוב פעם אנחנו