媒介
學 Swift 也有一段時光了,做了一些小的 demo。一向想做個完全的項目,發明這邊黉捨的外賣訂餐也逐步風行起來,不像中國有那末多壯大的外賣軟件,美國也有,但不多,最少中國人對那些軟件都不太熟知也不怎樣用。盤算專門針對午飯的外賣做個app,做了幾天,只做出個 UI,看上去很小的軟件,老手做起來感到器械照樣有點多。 Swift 若何與後端交互 之類的以後再漸漸學吧,稀有據庫之類的我都挺熟習,SQL 或許 MongoDB。
目次
在這個 app 中,一切 UI 都是用代碼創立的,你可以在 100 Days of Swift 看到,我之前演習的時刻都是用的 storyboard,然則到了10頁以上感到 storyboard 就開端有點亂了,特殊是那些 segue 的線牽得滿屏幕都是的時刻。以後我就開端用 SnapKit 做 UI 了,固然比起 CSS 來,照樣有點不便利,但用起來感到還行。上面我年夜概枚舉了一些完成的根本功效:
引誘頁
午飯菜單(tableView)
購物車,動畫
下拉刷新
自界說小我主頁 (collectionView)
Reminder 和 Setting 須要後台,就用了 Alert 來簡略呼應了
全屏右滑加入
詳細代碼請看我的 Github, 上面我就重要展現一下後果,略微講一下完成進程,代碼中已有許多正文。
引誘頁
引誘頁我是用 collectionView 做的,剛開端先斷定要不要進入引誘頁,假如版本更新,則進入。collectionView 滑動偏向設置為 .horizontal ,設置隨意率性數目的頁數。添加一個啟動的 startButton ,設置前幾頁都為 startButton.isHidden = true ,最初一頁的時刻顯示出來,再添加一個漸出的顯示動畫。
菜單和購物車
shoppingCart
菜單可以下拉刷新,本盤算自界說下拉刷新,就像 ALin 的項目中那樣,然則似乎有點成績,我就用了自帶的UIRefreshControl ,下拉的時刻顯示刷新的時光,略微調劑了下時光的 format。代碼很簡略
let dateString = DateFormatter.localizedString(from: NSDate() as Date, dateStyle: .medium, timeStyle: .short)
self.refreshControl.attributedTitle = NSAttributedString(string: "Last updated on \(dateString)", attributes: attributes)
self.refreshControl.tintColor = UIColor.white
然後做了個購物車的動畫,將菜單裡的圖片先縮小後減少“拋入”購物車,實際上是沿著 UIBezierPath 走的一個途徑,這段動畫完了以後,在 animationDidStop() 裡做購物車圖片的發抖,和顯示購置的物品數目,誰人 countLabel 是個長寬都為 15 的在購物車圖片右上角的 UILabel() 。
先完成一個回調辦法,當點擊了cell上的購置按鈕後觸發
func menuListCell(_ cell: MenuListCell, foodImageView: UIImageView) { guard let indexPath = tableView.indexPath(for: cell) else { return } // retrieve the current food model, add it to shopping cart model let model = foodArray[indexPath.section][indexPath.row] addFoodArray.append(model) // recalculate the frame of imageView, start animation var rect = tableView.rectForRow(at: indexPath) rect.origin.y -= tableView.contentOffset.y var headRect = foodImageView.frame headRect.origin.y = rect.origin.y + headRect.origin.y - 64 startAnimation(headRect, foodImageView: foodImageView) }
這是點擊購置以後的動畫完成:
fileprivate func startAnimation(_ rect: CGRect, foodImageView: UIImageView) { if layer == nil { layer = CALayer() layer?.contents = foodImageView.layer.contents layer?.contentsGravity = kCAGravityResizeaspectFill layer?.bounds = rect layer?.cornerRadius = layer!.bounds.height * 0.5 layer?.masksToBounds = true layer?.position = CGPoint(x: foodImageView.center.x, y: rect.minY + 96) KeyWindow.layer.addSublayer(layer!) // animation path path = UIBezierPath() path!.move(to: layer!.position) path!.addQuadCurve(to: CGPoint(x:SCREEN_WIDTH - 25, y: 35), controlPoint: CGPoint(x: SCREEN_WIDTH * 0.5, y: rect.origin.y - 80)) } groupAnimation() }
這是縮小,減少,拋入購物車的組動畫
// start group animation: throw, larger, smaller image fileprivate func groupAnimation() { tableView.isUserInteractionEnabled = false // move path let animation = CAKeyframeAnimation(keyPath: "position") animation.path = path!.cgPath animation.rotationMode = kCAAnimationRotateAuto // larger image let bigAnimation = CABasicAnimation(keyPath: "transform.scale") bigAnimation.duration = 0.5 bigAnimation.fromValue = 1 bigAnimation.toValue = 2 bigAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) // smaller image let smallAnimation = CABasicAnimation(keyPath: "transform.scale") smallAnimation.beginTime = 0.5 smallAnimation.duration = 1 smallAnimation.fromValue = 2 smallAnimation.toValue = 0.5 smallAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaSEOut) // group animation let groupAnimation = CAAnimationGroup() groupAnimation.animations = [animation, bigAnimation, smallAnimation] groupAnimation.duration = 1.5 groupAnimation.isRemovedOnCompletion = false groupAnimation.fillMode = kCAFillModeForwards groupAnimation.delegate = self layer?.add(groupAnimation, forKey: "groupAnimation") }
組動畫停止後的一些動畫後果。
// end image animation, start other animations func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { if anim == layer?.animation(forKey: "groupAnimation") { // start user interaction tableView.isUserInteractionEnabled = true // hide layer layer?.removeAllAnimations() layer?.removeFromSuperlayer() layer = nil // if user buy any food, show the count label if self.addFoodArray.count > 0 { addCountLabel.isHidden = false } // show the count label let goodCountAnimation = CATransition() goodCountAnimation.duration = 0.25 addCountLabel.text = "\(self.addFoodArray.count)" addCountLabel.layer.add(goodCountAnimation, forKey: nil) // shopping cart shaking let cartAnimation = CABasicAnimation(keyPath: "transform.translation.y") cartAnimation.duration = 0.25 cartAnimation.fromValue = -5 cartAnimation.toValue = 5 cartAnimation.autoreverses = true cartButton.layer.add(cartAnimation, forKey: nil) } }
購物車外面可以增長/削減購置數目,總價隨著會靜態更改。重要是有效到了兩個器械,一個是 selected 變量,一個是 reCalculateCount() 函數。依據 selected 來決議最初的總價,假如有更改,則從新盤算 (reCalculateCount)。
fileprivate func reCalculateCount() { for model in addFoodArray! { if model.selected == true { price += Float(model.count) * (model.vipPrice! as NSString).floatValue } } // assign price let attributeText = NSMutableAttributedString(string: "Subtotal: \(self.price)") attributeText.setAttributes([NSForegroundColorAttributeName: UIColor.red], range: NSMakeRange(5, attributeText.length - 5)) totalPriceLabel.attributedText = attributeText price = 0 tableView.reloadData() }
沒有完成 Pay() 功效。盤算以後測驗考試 Apple Pay ,之前用慣了付出寶,剛來美國的時刻很難熬痛苦,其實許多處所中都城曾經比美國好許多了。還好如今有了 Apple Pay ,還挺好用的。
自界說小我主頁
profile
原來盤算做成簡書那樣,然則。。作為老手感到照樣有點難度。也是由於我這 app 裡沒有需要完成那些,就沒細心研討。
如後面提到的這頁用的 collectionView,兩個 section,一個是 UserCollectionViewCell , 上面是 HistoryCollectionViewCell 。 上面這個 section 像一個 table 的 section,有一個會主動懸浮的 header,這 header 用的是 ALin 年夜神的輪子, LevitateHeaderFlowLayout() ,固然這個文件的 copyright 是用他的名字的。
class CollectionViewFlowLayout: LevitateHeaderFlowLayout { override func prepare() { super.prepare() collectionView?.alwaysBounceVertical = true scrollDirection = .vertical minimumLineSpacing = 5 minimumInteritemSpacing = 0 } }
這項目整體來講應當算很小的,假如後端也完成了,也算一個蠻完全的小項目了吧。
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐本站。
【iOS開源一個簡略的訂餐app UI框架】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!