Prowadzący: p. Maciej Mendela Kontakt do mnie: mmendela[małpa]tl[kropa]krakow[kropa]pl Konta tymczasowe na MacMini: - zastępstwo - bez hasła Ocenianie: SYSTEM PUNKTOWY (punkty moje i innych uczących tego przedmiotu są wspólne) Sposoby sprawdzania osiągnięć edukacyjnych uczniów: - sprawdzian - ćwiczenia, projekty - kartkówka Przelicznik punków na stopień: od 100% – stopień celujący; 90% do mniej niż 100% – stopień bardzo dobry; 70% do mniej niż 90% – stopień dobry; 50% do mniej niż 70% – stopień dostateczny; 40% do mniej niż 50% – stopień dopuszczający; mniej niż 40% możliwych do uzyskania punktów – stopień niedostateczny. poprawa po terminie -> średnia arytmetyczna Niesamodzielna praca - "podkładanie" kodu (podczas oceny zadaję ewentualne pytania weryfikujące dotyczące kodu / procesu powstawania): = oszustwo - nic nie wnosi w Twój rozwój - Ty otrzymujesz zero punktów bez możliwości ich poprawy (plagiat) - zero punktów otrzymują też pozostałe osoby zamieszane w ten proceder nie wnikam kto jest autorem pracy, kto ukradł, czy to świadome działanie czy nie zabezpieczaj swoje kody/miejsca ich składowania! Pamiętaj, że termin jest ostatecznym! Jeśli będziesz nieobecny/cna a mija termin to koniecznie wyślij oceniany materiał na mojego maila - ocenimy jak wrócisz. Wymagania edukacyjne: ndst nie spełnia kryteriów na dop dop - instaluje środowiska programistyczne do tworzenia aplikacji mobilnych - projektuje szablon interfejsu aplikacji mobilnej oraz jej funkcjonalność - uruchamia aplikację mobilną na urządzeniu wirtualnym i fizycznym - projektuje szablon interfejsu aplikacji mobilnej oraz jej funkcjonalność - zapisuje kod natywnej aplikacji mobilnej na system iOS lub Android w wybranym języku programowania - stosuje odpowiedni język programowania dla aplikacji mobilnych ze względu na systemy mobilne - planuje wykonanie zadania - ponosi odpowiedzialność za podejmowane działania dst - przygotowuje elementy UI (przyciski, nawigację, okna dialogowe, listy, formularze, paski narzędziowe, grafikę, animacje, dźwięk) zgodnie z szablonem interfejsu aplikacji i jej funkcjonalnością - uruchamia wirtualne urządzenia i zarządza nimi - zarządza pakietami rozszerzeń - stosuje monitoring zdarzeń i programuje ich obsługę - waliduje i obsługuje dane wejściowe - wykonuje operacje na danych i plikach z danymi dostępnych wewnętrznie i zewnętrznie - dobiera sposób przechowywania danych i dostępu do nich w aplikacji mobilnej (m.in. prostych danych, danych wewnętrznych i zewnętrznych, plików zasobów, baz danych) db - tworzy klasy i obiekty - integruje środowisko programistyczne z systemem kontroli wersji - korzysta z danych zewnętrznych JSON - stosuje API do połączeń z bazami danych oraz do obsługi danych wejściowych od użytkownika bdb - przygotowuje aplikację mobilną do publikacji w sklepie - implementuje interakcję i obsługę użytkownika w oparciu o dane wejściowe z różnych sensorów (środowiskowych, pozycyjnych, ruchu) i sprzętowe kontrolery mediów (np. ekran dotykowy, kamerę) cel - optymalizuje elementy graficzne aplikacji mobilnej z uwzględnieniem sprzętowych zasobów pamięciowych i ich konsumpcji - optymalizuje kod aplikacji i monitoruje jej wydajność za pomocą wbudowanych narzędzi Warunki i tryb otrzymania wyższej niż przewidywana rocznej oceny klasyfikacyjnej z zajęć edukacyjnych: Statut: § 38b. 13. Na co najmniej 7 dni przed datą zakończenia klasyfikacji nauczyciele prowadzący poszczególne zajęcia edukacyjne oraz wychowawca klasy są obowiązani poinformować ucznia o przewidywanych dla niego rocznych ocenach klasyfikacyjnych z zajęć edukacyjnych i przewidywanej rocznej ocenie klasyfikacyjnej zachowania. 13c. Ocena klasyfikacyjna nie może być niższa niż przewidywana. 20. Uczeń lub jego rodzice mogą zwrócić się do nauczyciela o ustalenie wyższej niż przewidywana rocznej oceny klasyfikacyjnej. Prośba może być wyrażona ustnie lub w formie pisemnej. 21. Nauczyciel prowadzący dane zajęcia edukacyjne jest zobowiązany dokonać analizy zasadności wniosku, o którym mowa w ust. 20. 22. Nauczyciel dokonuje analizy wniosku w oparciu o udokumentowane realizowanie obowiązków określonych w § 38 ust. 9. W oparciu o tę analizę może ocenę podwyższyć, utrzymać lub przed posiedzeniem klasyfikacyjnym dokonać sprawdzenia wiedzy i umiejętności ucznia w stosowanych przez siebie formach i w obszarach, które uzna za konieczne. Tak ustalona ocena nie może być niższa od proponowanej wcześniej i jest ostateczną w tym trybie postępowania.
Swift - Strona domowa Teoria na dziś: Podstawy (do Error Handling) Operatory If, pętle (for-in, while, repeat-while) Kompilator online - tutaj OnlineSwiftPlayground - tutaj lub VSC (można doinstalować dodatek "Swift") lub kompilacja poleceniem swift Na Windows trzeba zainstalować Swifta. Dodatkowo:
Kompilator online - tutaj OnlineSwiftPlayground - tutaj Dokumentacja - String Tematyka:
Kompilator online - tutaj OnlineSwiftPlayground - tutaj Dokumentacja - Dictionary, Array Dictionary - wybrana tematyka:
Dokumentacja - Set Tematyka:
Zapraszam do wykonania ćwiczenia na dziś i rozpoczęcia zadania.
Zadanie: oprogramuj utworzone w zeszłej lekcji widoki do kalkulatora BMI - dodaj ikonę aplikacji - trzy różne obrazki w zależności od wyniku BMI - wynik podawany w zaokrągleniu do jednej cyfry po przecinku - zabezpiecz by liczył tylko kiedy są wpisane liczby BMI = masa / (wzrost ^ 2) < 18,5 – niedowaga 18,5–24,99 – wartość prawidłowa ≥ 25,0 – nadwaga Ustawianie odpowiedniego obrazka z kodu (obrazki umieszczone w assets'ach): - dodajesz outlet do obrazka (UIImageView) np. o nazwie secik - secik.image = UIImage(named: "name_of_image_set")
Zadnie:docelowo tworzymy grę "Memory" - dodaj NavigationController - widok 1: wybór trybów [trudny (7x4) / łatwy (4x3)] a) użyj kontrolki SegmentedControl (właściwość selectedSegmentIndex - zwraca index) b) ustaw ją na środku urządzenia c) dodaj w tło widoku grafikę - widok 2: a) w przestrzeni roboczej (bez statusBar'a i navigationBar'a - patrz uwagi niżej) rozmieść odpowiednią ilość kwadratowych puzzli b) po tapnięciu "wyprintuj" jego tag. - wyliczaj szerokość bloczka tak by układ zajął całą szerokość lub wysokość urządzenia (jak najmniej "strat" widoku) - po zmianie orientacji przelicz na nowo pozycję bloczków ("odśwież" wodok) - paczka z grafikami Rysunki poglądowe:Pomocne kody/teoria:![]()
![]()
- wybierasz opcję show
- kodzisz
W zadniu dodajemy:- możliwość szukania par - ponowne przeliczenie położenia pozycji puzzli po obrocie iPad'a - po znalezieniu pary puzzle nie znikają (wyłączamy możliwość ich kliknięcia) - po wygranej wyświetlamy okno dialogowe z informacją o ilości ruchów i możliwością powrotu do menu - po informacji cofamy do wyjściowego widokuPomoce:sleep, usleep - opóźnienie (np. sleep(2) - 2[s]) timeout po 0.5[s] DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { code } właściwość buttona isEnabled blokuje go lub isUserInteractionEnabled - brak możliwości interakcji Przy obrocie IPada masz dwa rozwiązania: 1. Ponowne wywołanie funkcji generującej viewWillTransition -> patrz poprzednia lekcja UWAGA: możesz zmienić pozycje już istniejących buttonów poprzez ponowne ustawienie właściwości frame 2. Zablokowanie rotacji (przetestuj, ale proszę o rozwiązanie 1) w pliku info.plist Supported interface orientations (iPad) - zostawiasz wspierane orientacje lub w ustawiniach projektu:Okno dialogowe https://developer.apple.com/documentation/uikit/windows_and_screens/getting_the_user_s_attention_with_alerts_and_action_sheets Cofanie navigationController .popToRootViewController .popViewController
Zadanie: wykonaj stoper jak na poniszych screenach (działanie - patrz stoper na IPadzie)![]()
Pomoce: 1. czas Date().timeIntervalSince1970 // pobieranie aktualnego timestampa Date(timeIntervalSince1970: timestamp); // tworzenie z timestampa do prezentacji konkretnych składowych używamy Formatera: let dF = DateFormatter(); dF.locale = Locale(identifier: "pl_PL") dF.setLocalizedDateFormatFromTemplate("MM-dd-yyyy HH:mm") let format = dF.string(from: date_do_formatowania) 2. Timer (odpowiednik setInterval z JS) timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(update), userInfo: nil, repeats: true) RunLoop.current.add(timer!, forMode: .common); //by przy przewijaniu listy nie zatrzymywał się zegar - przetestuj bez i z timer?.invalidate(); //zatrzymanie pamiętaj o: @objc func update() { } 3. UITableView - dodajesz TableView - do niego TableViewCell (wzorcowy wiersz), nadajesz "Identifier" (u mnie cell)
- do wiersza dodajesz Labelki (u mnie left, mid, right) - w klasie dodajesz UITableViewDataSource i UITableViewDelegate lub: extension ViewController: UITableViewDelegate { } extension ViewController: UITableViewDataSource { } - wykorzystujesz (tableView): numberOfSections - ilość sekcji (u nas 1) numberOfRowsInSection - ilość wierszy w sekcji cellForRowAt - uzupełnia wiersze - dodaj klasę z outletami do Labelek z wzorcowego wiersza:
class TableData : UITableViewCell { @IBOutlet weak var right: UILabel! @IBOutlet weak var left: UILabel! @IBOutlet weak var mid: UILabel! }- w cellForRowAt korzystamy z opcji reusable cell (oszczędność pamięci): let cell = tab.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableData; indexPath.row - aktualny wiersz - dostęp do naszych labelek poprzez: cell.left/mid/right (text, textColor) 4. Płotki - zaokrąglanie Buttona: buttonOutlet.layer.cornerRadius = width/2 - border UIView: let thickness: CGFloat = 0.5 let bottomBorder = CALayer() bottomBorder.frame = CGRect(x:0, y: subView.frame.size.height - thickness, width: subView.frame.size.width, height:thickness) let gray = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1) bottomBorder.backgroundColor = gray.cgColor outletUiView.layer.addSublayer(bottomBorder) - UIColor: UIColor.yellow UIColor(red: 109/255, green: 133/255, blue: 86/255, alpha: 1) // r/g/b od 0 - 1 => konieczność /255 - Array: append, insert - Button: buttonOutlet .setTitle("Stop", for: .normal) .backgroundColor = UIColor ... .setTitleColor(.red, for: .normal)
Zadanie:W projekcie dodaj widok z cyferblatem o funkcjonalnościach jak systemowy stoper tj. trzy odpowiednie wskazówki i zegar cyfrowy. Cyferblat możesz wrysowywać lub umieścić grafikę a rysować "tylko" wskazówki. Przykładowa grafika cyferblatuBy uzyskać przejście między widokami można użyć UIScrollView i UIPageControl (możesz posiłkować się tym tutkiem): 1. w widoku głównym dodaj równolegle UIScrollView i UIPageControl, dodaj im outlety (sv, pc).2. Widoki dla UISCrollView proponuję zachowywać w osobnych plikach w tym celu: - utwórz grupę (np. views), - dodaj odpowiednią ilość plików xib ("New File..." -> User Inerface, View) - i pliki swift ("New File ..." -> Coca Touch Class) z odpowiednimi klasami (zepnij je z widokami w xib)
3. Utwórz właściwość do przechowania widoków
var slides = Array4. Określ wymiary i cechy UIScrollView (kontener dla widoków)() sv.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height) sv.isPagingEnabled = true // w przypadku dwóch widoków - nadmiarowe // odpowiednie paski przewijania sv.showsVerticalScrollIndicator = false sv.showsHorizontalScrollIndicator = false5. Dodaj widoki i ich wymiarylet slideA : SlideA = Bundle.main.loadNibNamed("SlideA", owner: self, options: nil)?.first as! SlideA let slideB : SlideB = Bundle.main.loadNibNamed("SlideB", owner: self, options: nil)?.first as! SlideB slideA.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height) slideB.frame = CGRect(x: view.frame.width, y: 0, width: view.frame.width, height: view.frame.height) slides = [slideA, slideB]6. Umieść widoki w kontenerzesv.addSubview(slideA) sv.addSubview(slideB)uwaga: zauważ, że każdy widok ma wymiar kontenera (view.frame.width), potrzebujemy go przepełnić. Działanie UIScrollView jest analogiczne do diva o określonej szerokości w dodanych w nim N elementów (jak w sliderze). Regulacja widoku następuje przez paski przewijania kontenera. 7. Ustawiamy wymiary zawartości UIScrollViewsv.contentSize = CGSize(width: view.frame.width*2, height: view.frame.height-24) // 24 - pobierz programowo wartość StatusBara'auwaga: contentSize jest dwa razy szerszy od wymiaru UIScrollView -> dwa widoki 8. Ilość "bombli" na UIPageControlpc.numberOfPages = slides.count9. Dodajemy UIScrollViewDelegate i delegate (sv.delegate = self) 10. Oprogramowujemy by po zmianie widoku zmieniał się "bomelek"func scrollViewDidScroll(_ scrollView: UIScrollView) { let pageIndex = round(sv.contentOffset.x/view.frame.width) pc.currentPage = Int(pageIndex) }11. By po zmianie "bombelka" zmieniał się widok dodajemy UIPageControl akcję "Value Changed" i ustawiamy odpowiedni offset@IBAction func change(_ sender: UIPageControl) { let x = CGFloat(sender.currentPage) * view.frame.width sv.contentOffset = CGPoint(x: x, y: 0) }uwaga: by przejście było płynne dodaj animację (zmiana x w czasie, na kolejnej lekcji będzie jeszcze czas) 12. komunikacja z widokami odbywa się przez outlety w nich utworzone np.(slides[1] as! SlideB).textB.text="LOL" // textB - outlet do Label w widoku SlideB13. Rysowanie Następnym razem użyjemy - Core Graphics
13. Rysowanie Core Graphics Przykład rysujący linię:@IBOutlet weak var rys: UIImageView! ... UIGraphicsBeginImageContext(rys.bounds.size) rys.draw(rys.bounds) // kopia obecnej zawartości let ctx = UIGraphicsGetCurrentContext() ctx?.move(to: CGPoint(x: 0, y: 200)) ctx?.addLine(to: CGPoint(x: 200, y: 0)) ctx?.setLineWidth(10); ctx?.setStrokeColor(UIColor.black.cgColor) ctx?.strokePath() rys.image=UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() // zwolnienie pamięciW projekcie dodaj animacje (lewo/prawo) po kliknięciu "bomby". można użyć Timer.scheduledTimer (np. czas 0.01 i przesunięcie 25)
Termin:Wszystkie grupy: - do 18.06.2026Instrukcja oceny/oddania:- osobista prezentacja działania - po ocenie wysyłka zip'a z kodem/ami na mendela.pl/uploadPunktacja:Szczegóły zawsze przy danym temacie! Poniżej synteza BMI - max. 2p 1p - układ land/vert + ikona [cz.1] 1p - oprogramowanie kalkulatora [cz.2] MEMORY - max. 3p 1p - dynamiczne generowanie playfielda w zależności od trybu + ikona + układ land/vert [cz.1] 1p - odkrywanie/zakrywanie grafik (parowanie) [cz.2] 1p - zakończenie gry + UIAlert + powrót do menu (cała gra) [cz.3] STOPER - max. 5p 1p - cyfrowy zegar + start/stop 2p - w pełni działające zachowania w TableView m.in. zaznaczanie min/max, rundy, zerowanie, łączny/pośredni czas 1p - UIScrollView + UIPageControl z animacjami przejść 1p - cyferblat + działające wskazówki
Sala 309 Plan aktualny do 24.04 (uaktualnię po zmianach - maturzyści) w nawiasach podano minimalną ilość wolnych stanowisk (+chorzy/wagarowicze) Pn: 1 07:30 - 08:15 4Ic gr1, aplikacje klienckie [1] 2 08:25 - 09:10 4Ic gr1, aplikacje klienckie [1] 3 09:20 - 10:05 okienko [18] 4 10:15 - 11:00 4Ia gr2, aplikacje serwerowe [2] 5 11:15 - 12:00 4Ia gr2, aplikacje serwerowe [2] 6 12:10 - 12:55 4Ic gr2, aplikacje klienckie [1] 7 13:05 - 13:50 4Ic gr2, aplikacje klienckie [1] Wt: 1 07:30 - 08:15 4Ib gr2, aplikacje klienckie [2] 2 08:25 - 09:10 4Ib gr2, aplikacje klienckie [2] 3 09:20 - 10:05 okienko [18] 4 10:15 - 11:00 4Ia gr1, aplikacje serwerowe [brak] 5 11:15 - 12:00 4Ia gr1, aplikacje serwerowe [brak] 6 12:10 - 12:55 4Ic gr2, aplikacje serwerowe [1] 7 13:05 - 13:50 4Ic gr2, aplikacje serwerowe [1] Śr: 1 07:30 - 08:15 4Ic TŁ, zajęcia z wychowawcą s. 209 2 08:25 - 09:10 4Ib gr1, aplikacje serwerowe [1] 3 09:20 - 10:05 4Ib gr1, aplikacje serwerowe [1] 4 10:15 - 11:00 4P gr1, aplikacje webowe [5] 5 11:15 - 12:00 4P gr1, aplikacje webowe [5] 6 12:10 - 12:55 4Ia gr1, aplikacje klienckie [brak] 7 13:05 - 13:50 4Ia gr1, aplikacje klienckie [brak] 8 13:55 - 14:40 4P gr2, aplikacje webowe [brak] 9 15:00 - 15:45 4P gr2, aplikacje webowe [brak] Czw: 2 08:25 - 09:10 4Ia gr2, aplikacje klienckie [2] 3 09:20 - 10:05 4Ia gr2, aplikacje klienckie [2] 4 10:15 - 11:00 4Ib gr1, aplikacje klienckie [1] 5 11:15 - 12:00 4Ib gr1, aplikacje klienckie [1] Pt: 3 09:20 - 10:05 4Ib gr2, aplikacje serwerowe [2] 4 10:15 - 11:00 4Ib gr2, aplikacje serwerowe [2] 5 11:15 - 12:00 4Ic gr1, aplikacje serwerowe [1] 6 12:10 - 12:55 4Ic gr1, aplikacje serwerowe [1] +wolniejsze jedno stanowisko na zapleczu (daj znać via Librus to je przygotuję) [1]