codeSwiftBlog带我飞2

高仿小日子Swift2.0

2015-09-21  本文已影响20862人  Top_熊

不知不觉十一马上到了,承诺给大家分享的Swift项目也该兑现了,本次项目为高仿小日子,废话不多说,先看效果吧


探店效果图探店效果图
探店详情页效果图探店详情页效果图
附近地图效果图附近地图效果图
体验效果图体验效果图
分类效果图分类效果图
我的效果图我的效果图
搜索效果图搜索效果图
摇一摇效果图摇一摇效果图

更多效果请用Xcode7.0正式版运行程序查看

此项目相对来说比较简单,之前用Swift1.2编写的,9月18号,苹果发布了Xcdoe7.0正式版,小熊也将代码更新到了Swift2.0,由于Swift语言还不稳定,每个版本都会出现语法修改,本项目用最新的Xcode7正式版编写,建议使用Xcode7正式版运行工程,项目的接口依然有加密,抱着学习的态度,小熊截取了网络请求返回数据,并且将数据写入到了本地,所以读者用到的数据都是固定的

本来想挑一个复杂点的项目分享给大家,考虑到公司的项目要在十一前上线,时间比较紧,以及自己对Swift语言还处于摸索阶段,经常也是连蒙加猜的,很多写法还是沿用OC的套路,不过相信对于大家学习Swift语言还是有一定帮助的.很多时候,小熊都是被一个很简单的语法卡住很久,比如如何动态实例化AnyClass对象,还有升级到2.0后,通过NSStringFromClass:方法创建对象是需要追加命名空间的前缀,我记忆很深刻...

此次写代码的过程中吸取了读者的提议,用的源代码管理工具是git,大家可以在项目的历史版本回退查看项目的从无到有是如何一步一步完善的,由于白天上班,晚上写这个项目,所以中间博客没有怎么更新,读者也可以从代码提交时间看出...都是半夜1 . 2点左右

在学习Swift语言中,自己也断断续续的总结了一些OC和Swift语法的区别,以及Swift于OC中相同方法的不用写法,我也会在后续时间发布到博客里,让大家避免不必要的麻烦,请持续关注小熊的博客


下面来介绍此项目的每个模块的思路,这里就按照程序运行展示的页面的顺序逐一与大家分析吧

引导页(新特性页面)

privete func showLeadpage() -> UIViewController {
    let versionStr = "CFBundleShortVersionString"
    let cureentVersion = NSBundle.mainBundle().infoDictionary![versionStr] as! String
    let oldVersion = (NSUserDefaults.standardUserDefaults().objectForKey(versionStr) as? String) ?? ""

    if cureentVersion.compare(oldVersion) == NSComparisonResult.OrderedDescending {
    NSUserDefaults.standardUserDefaults().setObject(cureentVersion, forKey: versionStr)
    NSUserDefaults.standardUserDefaults().synchronize()
    return LeadpageViewController()
    }

UITabbarController(KeyWindow.rootViewController)

 override func pushViewController(viewController: UIViewController, animated: Bool) {

    if self.childViewControllers.count > 0 {
        let vc = self.childViewControllers[0]

        if self.childViewControllers.count == 1 {
            backBtn.setTitle(vc.tabBarItem.title!, forState: .Normal)
        } else {
            backBtn.setTitle("返回", forState: .Normal)
        }

        viewController.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backBtn)
        viewController.hidesBottomBarWhenPushed = true
    }

    super.pushViewController(viewController, animated: animated)
}

左上角的城市

    let lastSelectedCityIndexPaht = selectedCurrentCity()
    collView.selectItemAtIndexPath(lastSelectedCityIndexPaht, animated: true, scrollPosition: UICollectionViewScrollPosition.None)
城市选择控制器城市选择控制器

探店如下图所示

探店效果图探店效果图

extension EventViewController: UIScrollViewDelegate {

    func scrollViewDidScroll(scrollView: UIScrollView) {

        // 解决弹出新的控制器后返回后contentSize自动还原的问题
        if loadFinishScrollHeihgt > webView.scrollView.contentSize.height && scrollView === webView.scrollView {
            webView.scrollView.contentSize.height = loadFinishScrollHeihgt
        }

        let offsetY: CGFloat = scrollView.contentOffset.y
        // 判断顶部自定义导航条的透明度,以及图片的切换
        customNav.alpha = 1 + (offsetY + NavigationH + EventViewController_ShopView_Height) / scrollShowNavH
        if offsetY + EventViewController_ShopView_Height >= -NavigationH && showBlackImage == false {
            backBtn.setImage(UIImage(named: "back_1"), forState: .Normal)
            likeBtn.setImage(UIImage(named: "collect_1"), forState: .Normal)
            sharedBtn.setImage(UIImage(named: "share_1"), forState: .Normal)
            showBlackImage = true
        } else if offsetY < -NavigationH - EventViewController_ShopView_Height && showBlackImage == true {
            backBtn.setImage(UIImage(named: "back_0"), forState: .Normal)
            likeBtn.setImage(UIImage(named: "collect_0"), forState: .Normal)
            sharedBtn.setImage(UIImage(named: "share_0"), forState: .Normal)
            showBlackImage = false
        }

        // 顶部imageView的跟随动画
        if offsetY <= -DetailViewController_TopImageView_Height - EventViewController_ShopView_Height {
            topImageView.frame.origin.y = 0
            topImageView.frame.size.height = -offsetY - EventViewController_ShopView_Height
            topImageView.frame.size.width = AppWidth - offsetY - DetailViewController_TopImageView_Height
            topImageView.frame.origin.x = (0 + DetailViewController_TopImageView_Height + offsetY) * 0.5
        } else {
            topImageView.frame.origin.y = -offsetY - DetailViewController_TopImageView_Height - EventViewController_ShopView_Height
        }

        // 处理shopView
        if offsetY >= -(EventViewController_ShopView_Height + NavigationH) {
            shopView.frame = CGRect(x: 0, y: NavigationH, width: AppWidth, height: EventViewController_ShopView_Height)
        } else {
            shopView.frame = CGRect(x: 0, y: CGRectGetMaxY(topImageView.frame), width: AppWidth, height: EventViewController_ShopView_Height)
        }

        // 记录scrollView最后的偏移量,用于切换scrollView时同步俩个scrollView的偏移值
        lastOffsetY = offsetY
    }
}

                if model?.title != nil {
                    titleStr = String(format: "<p style='font-size:20px;'> %@</p>", model!.title!)
                }

                if model?.tag != nil {
                    titleStr = titleStr?.stringByAppendingFormat("<p style='font-size:13px; color: gray';>%@</p>", model!.tag!)
                }
webView.stringByEvaluatingJavaScriptFromString("document.getElementsByTagName('body')[0].style.background='#F5F5F5';")

附近(效果如下图所示)

附近地图效果图附近地图效果图
        if sender.selected {
            UIView.transitionFromView(nearTableView, toView: mapView, duration: 1.0, options: UIViewAnimationOptions.TransitionFlipFromLeft, completion: nil)
        } else {
            UIView.transitionFromView(mapView, toView: nearTableView, duration: 1.0, options: UIViewAnimationOptions.TransitionFlipFromRight, completion: nil)
        }

体验

        // 估算cell的高度
        tableV.estimatedRowHeight = 200
         // 设置tableView的自动布局样式
        tableV.rowHeight = UITableViewAutomaticDimension

体验详情控制器效果如下图所示

搜索控制器(效果图如下)

搜索控制器搜索控制器

我的

用户头像View
/// MARK: 摄像机和相册的操作和代理方法
extension MeViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    /// 打开照相功能
    private func openCamera() {
        if UIImagePickerController.isSourceTypeAvailable(.Camera) {
            pickVC.sourceType = .Camera
            self.presentViewController(pickVC, animated: true, completion: nil)
        } else {
            SVProgressHUD.showErrorWithStatus("模拟器没有摄像头,请链接真机调试", maskType: SVProgressHUDMaskType.Black)
        }
    }
    
    /// 打开相册
    private func openUserPhotoLibrary() {
        pickVC.sourceType = .PhotoLibrary
        pickVC.allowsEditing = true
        presentViewController(pickVC, animated: true, completion: nil)
    }
    
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
        // 对用户选着的图片进行质量压缩,上传服务器,本地持久化存储
        if let typeStr = info[UIImagePickerControllerMediaType] as? String {
            if typeStr == "public.image" {
                if let image = info[UIImagePickerControllerEditedImage] as? UIImage {
                    var data: NSData?
                    let smallImage = UIImage.imageClipToNewImage(image, newSize: iconView!.iconButton.size)
                    if UIImagePNGRepresentation(smallImage) == nil {
                        data = UIImageJPEGRepresentation(smallImage, 0.8)
                    } else {
                        data = UIImagePNGRepresentation(smallImage)
                    }
                    
                    if data != nil {
                        do {
                            // TODO: 将头像的data传入服务器
                            // 本地也保留一份data数据
                            try NSFileManager.defaultManager().createDirectoryAtPath(theme.cachesPath, withIntermediateDirectories: true, attributes: nil)
                        } catch _ {
                        }
                        NSFileManager.defaultManager().createFileAtPath(SD_UserIconData_Path, contents: data, attributes: nil)
                        
                        iconView!.iconButton.setImage(UIImage(data: NSData(contentsOfFile: SD_UserIconData_Path)!)!.imageClipOvalImage(), forState: .Normal)
                        
                    } else {
                        SVProgressHUD.showErrorWithStatus("照片保存失败", maskType: SVProgressHUDMaskType.Black)
                    }
                }
            }
        } else {
            SVProgressHUD.showErrorWithStatus("图片无法获取", maskType: SVProgressHUDMaskType.Black)
        }
        
        picker.dismissViewControllerAnimated(true, completion: nil)
    }
    
    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        pickVC.dismissViewControllerAnimated(true, completion: nil)
    }
}

摇一摇

摇一摇效果图摇一摇效果图
    override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?) {
        tableView!.hidden = true
        let animateDuration: NSTimeInterval = 0.3
        let offsetY: CGFloat = 50
        
        UIView.animateWithDuration(animateDuration, animations: { () -> Void in
            self.yaoImageView1.transform = CGAffineTransformMakeTranslation(0, -offsetY)
            self.yaoImageView2.transform = CGAffineTransformMakeTranslation(0, offsetY)
            
            }) { (finish) -> Void in
                let popTime = dispatch_time(DISPATCH_TIME_NOW,Int64(0.5 * Double(NSEC_PER_SEC)))
                dispatch_after(popTime, dispatch_get_main_queue(), { () -> Void in
                    
                    UIView.animateWithDuration(animateDuration, animations: { () -> Void in
                        self.yaoImageView1.transform = CGAffineTransformIdentity
                        self.yaoImageView2.transform = CGAffineTransformIdentity
                        }, completion: { (finish) -> Void in

                            self.loadShakeData()
                            // 音效
                            AudioServicesPlayAlertSound(self.soundID!)
                    })
                })
        }

清理缓存

三方分享


关于项目的介绍基本就这么多了,更多的细节和内容直接看代码来的更快捷一些,对于Swift小熊也是又爱又恨,相信随着版本的不断更新,Swift语言也会越来越趋于稳定,Xcode对Swift的支持也会越来越好的,总算对自己的承诺有了一个小小的交代,如果有小熊的项目有帮助到大家,请到我的GitHub点个星,项目中会有很多不足之处,欢迎到我的博客留言与交流,小熊希望与大家共同进步_~,提前祝大家十一快乐


直接打开运行工程

打开工作组运行工程打开工作组运行工程

代码下载地址

代码下载地址,欢迎点赞和反馈

小熊的技术博客

点击链接我的博客

小熊的新浪微博

我的新浪微博


本文为作者原著,欢迎转载,转载请注明作者出处

上一篇 下一篇

猜你喜欢

热点阅读