Sian 发表于 2014-4-11 23:06:54

ios实战开发之仿新浪微博(第一讲:新特性展示)

本帖最后由 Sian 于 2015-7-13 09:12 编辑

1、效果展示

http://player.youku.com/player.php/sid/XNjk3NTc1ODIw/v.swf

2、设计说明
2.1 规范文件结构,总体思想:将类单独创建文件夹分类管理,图片、音频等资源分类管理,如图:



2.2 ios程序运行过程解释,参考:ios程序运行过程解析
2.3 新特性展示思路,参考:ios实战开发之UIScrollView图片浏览器
2.4 细节加工
2.4.1 创建UIImage的Category,新创建一个方法来自适应iphone不同尺寸屏幕的图片展示
2.4.2 创建全局宏,抽取常用代码及变量的统一定义与修改,编写一个Common.h文件

3、关键代码
SAAppDelegate.h
//
//SAAppDelegate.h
//SianWeibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import <UIKit/UIKit.h>

@class SAViewController;

@interface SAAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) SAViewController *viewController;

@end

SAAppDelegate.m
//
//SAAppDelegate.m
//SianWeibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "SAAppDelegate.h"
#import "SANewfeatureController.h"
#import "SAMainController.h"

@implementation SAAppDelegate

#pragma mark 应用程序加载完毕后调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 创建一个窗口
    self.window = [ initWithFrame:[ bounds]];
   
    /*****************************************************************/
   
    // 版本号在info.plist中的key值
    NSString *key = (NSString *)kCFBundleVersionKey;
   
    // 从info.plist中取出当前版本号
    NSString *version = .infoDictionary;
   
    // 从沙盒中取出上次存储的版本号
    NSString *saveVersion = [ objectForKey:key];
   
    // 判断是否为第一次使用该版本,如果是则进入新特性展示,否则直接进入微博主界面
    if () {
      // NSLog(@"使用过的版本");
      self.window.rootViewController = [ init];       // 非第一次使用该版本直接进入主界面视图
   
    } else {
      [ setObject:version forKey:key];   // 将新的版本号写入到沙盒中
      [ synchronize];                  // 立即同步

      // NSLog(@"第一次使用该版本");
      self.window.rootViewController = [ init]; // 第一次使用该版本进入新特性视图
    }
   
    /*****************************************************************/
   
    // 将窗口设置为显示,keyWindow为主窗口,只有主窗口才能与用户交互
    ;
    return YES;
}

#pragma mark 程序被挂起时调用
- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    // NSLog(@"程序被挂起");
}

#pragma mark 程序进入后台时调用
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    // NSLog(@"程序进入后台");
}

#pragma mark 应用再次进入前台时调用
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    // NSLog(@"程序进入前台");
}

#pragma mark 处于活动状态时调用
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    // NSLog(@"程序被激活");
}

#pragma mark 程序被终结时调用
- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    // NSLog(@"程序被终结时调用");
}

@end

SANewfeatureController.h
//
//SANewfeatureController.h
//SianWeibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface SANewfeatureController : UIViewController

@end

SANewfeatureController.m
//
//SANewfeatureController.m
//SianWeibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//版本新特性界面

#import "SANewfeatureController.h"
#import "UIImage+SA568h.h"
#import "SAMainController.h"
#define kPicCount 4
#define kPageControlW 150

@interface SANewfeatureController () <UIScrollViewDelegate>
{
    UIPageControl   *_pageControl;
    CGSize          _size;
}

@end

@implementation SANewfeatureController

#pragma mark 自定义view
- (void)loadView
{
    // self.view直接使用UIImageView设置ImageView尺寸与位置
    UIImageView *imageView = [ init];
    imageView.image = ;
    imageView.frame = .bounds;
    imageView.userInteractionEnabled = YES;               // 开启当前控件与用户交互
    self.view = imageView;                                  // 基本View设置为新创建ImageView
}

#pragma mark 视图加载完毕后调用
- (void)viewDidLoad
{
    ;
    _size = .bounds.size;            // 全局定义一个屏幕宽高值供后续使用
    UIScrollView *scrollView = ;      // 创建一个scrollView
    UIPageControl *pageControl = ;   // 创建一个pageControl
   
    ;                     // pageControl加载到视图
    ;                      // scrollView加载到视图
}

#pragma mark - 控件添加方法
#pragma mark 添加scrollView控件
- (UIScrollView *)creatScrollView       // 控件的创建单独抽象成方法
{
    // 创建scrollView设置尺寸位置及相关属性
    UIScrollView *scrollView = [ init];
    scrollView.frame = self.view.bounds;
    scrollView.contentSize = CGSizeMake(_size.width * kPicCount, 0);
    scrollView.pagingEnabled = YES;
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.delegate = self;
   
    //创建新特性图片设置尺寸位置并添加到scrollView
    for (int i = 0; i < kPicCount; i++) {
      UIImageView *imageView = [ init];
      ;
      NSString *imageName = ;
      imageView.image = ;
      imageView.frame = CGRectMake(_size.width * i, 0, _size.width, _size.height);
      // 最后一张图片上添加两个子视图(分享选项与体验微博按钮)
      if ( i == kPicCount - 1) {
            imageView.userInteractionEnabled = YES;         // 开启当前imageView用户交互属性
            ;                // 调用方法创建分享选项视图
            ;                // 调用方法创建体验微博按钮视图
      }
    }
    return scrollView;
}

#pragma mark 添加pageControl控件
- (UIPageControl *)creatPageControl   // 控件的创建单独抽象成方法
{
    UIPageControl *pageControl = [ init];
    pageControl.center = CGPointMake(_size.width * 0.5, _size.height * 0.95);
    pageControl.bounds = CGRectMake(0, 0, kPageControlW, 0);
    pageControl.numberOfPages = kPicCount;
   
    // pageControl指示符颜色用图片代替,效果更美观
    UIImage *checkedPointImage = ;
    pageControl.currentPageIndicatorTintColor = ;
    UIImage *pointImage = ;
    pageControl.pageIndicatorTintColor = ;
   
    // scrollView的代理方法中可设置pageControl的当前页属性,将创建好的pageControl赋值给成员变量全局访问
    _pageControl = pageControl;
    return pageControl;
}

#pragma mark - 按钮添加方法
#pragma mark 分享按钮添加
- (void)addShareButton:(UIImageView *)imageView         // 新特性展示最后一张图片中"分享"视图单独抽象成方法
{
    // 用按钮来实现"分享"视图
    UIButton *shareButton = ;
    shareButton.adjustsImageWhenHighlighted = NO;       // 去除按钮的高亮效果
   
    // 设置按钮两个状态,循环点击时循环切换
    UIImage *shareNomalImage = ;
    UIImage *shareSelectedImage = ;
    ;
    ;
   
    // 设置按钮尺寸位置
    shareButton.center = CGPointMake(_size.width * 0.5, _size.height * 0.7);
    CGSize shareBtnSize = shareNomalImage.size;
    shareButton.bounds = CGRectMake(0, 0, shareBtnSize.width, shareBtnSize.height);
    shareButton.selected = YES;                         // 默认为已选择状态
   
    // 创建按钮监听事件,每次点击都修改一次selected状态
    ;
    ;
}

#pragma mark 立即体验按钮添加
- (void)addStartButton:(UIImageView *)imageView         // 新特性展示最后一张图片中"体验"按钮单独抽象成方法
{
    // 创建按钮,设置尺寸宽高等属性
    UIButton *startButton = ;
    UIImage *startNomalImage = ;
    UIImage *startHighlightImage = ;
    ;
    ;
    startButton.center = CGPointMake(_size.width * 0.5, _size.height * 0.8);
    CGSize startBtnSize = startNomalImage.size;
    startButton.bounds = (CGRect){CGPointZero, startBtnSize};
   
    // 按钮监听事件,点击该按钮进入微博主界面
    ;
    ;

}

#pragma mark - 按钮事件处理方法
#pragma mark 分享按钮事件处理
-(void)shareButtonEven:(UIButton *)button               // "分享"按钮事件处理
{
    button.selected = !button.selected;
    // 按钮的selected属性取反,实现循环点击-选择或取消分享
}

#pragma mark 立即体验按钮事件处理
-(void)startButtonEven:(UIButton *)button               // "体验"按钮事件处理
{
    // 该按钮事件使程序切换到微博主界面
    self.view.window.rootViewController = [ init];
}

#pragma mark - scrollView代理方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView   // 利用代理方法计算出pageControl中当前当前页属性
{
    _pageControl.currentPage =scrollView.contentOffset.x / scrollView.frame.size.width;
    // contentOffset.x的值除以视图宽度得到的整数相当于当前的页码
}

@end
SAMainController.h
//
//SAMainController.h
//SianWeibo
//
//Created by yusian on 14-4-11.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface SAMainController : UIViewController

@end

SAMainController.m
//
//SAMainController.m
//SianWeibo
//
//Created by yusian on 14-4-11.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//主程序界面

#import "SAMainController.h"

@interface SAMainController ()

@end

@implementation SAMainController

- (void)viewDidLoad
{
    ;
   
    // 临时Table
    self.view.backgroundColor = ;
    UILabel *tempLable = [ init];
    tempLable.center = self.view.center;
    tempLable.bounds = CGRectMake(0, 0, self.view.frame.size.width * 0.8, 50);
    tempLable.text = @"微博主界面建设中...";
    tempLable.textColor = ;
    tempLable.textAlignment = NSTextAlignmentCenter;
    tempLable.font = ;
    ;
   
}

@end

UIImage+SA568h.h
//
//UIImage+SA568h.h
//SianWeibo
//
//Created by yusian on 14-4-11.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//分类实现iphone5自动加载568h@2x尺寸图片

#import <UIKit/UIKit.h>

@interface UIImage (SA568h)

+ (UIImage *)fullScreenImage:(NSString *)string;

@end

UIImage+SA568h.m
//
//UIImage+SA568h.m
//SianWeibo
//
//Created by yusian on 14-4-11.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//

#import "UIImage+SA568h.h"

@implementation UIImage (SA568h)

+ (UIImage *)fullScreenImage:(NSString *)string
{
    // 根据屏幕高度判断iphone5
    if (isIPhone5) {
      
      // 1、获取文件扩展名
      NSString *ext = ;
      
      // 2、去掉文件扩展名
      string = ;
      
      // 3、添加iphone5特殊文件名串
      string = ;
      
      // 4、添加扩展名
      string = ;
   
    }
    return ;
}

@end

SACommon.h
//
//SACommon.h
//SianWeibo
//
//Created by yusian on 14-4-10.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//公共头文件

// 判断是否为iphone5的宏
#define isIPhone5 (.bounds.size.height == 568)

// 用MyLog替代NSLog,调试时输出日志,正式发布时自动取消日志输出代码
#ifdef DEBUG
#define MyLog(...) NSLog(__VA_ARGS__)
#else
#define MyLog(...)
#endif

4、源代码下载
**** Hidden Message *****

相关主题链接
1、ios实战开发之仿新浪微博(第一讲:新特性展示)
2、ios实战开发之仿新浪微博(第二讲:主框架搭建)
3、ios实战开发之仿新浪微博(第三讲:更多界面搭建)
4、ios实战开发之仿新浪微博(第四讲:OAuth认证)
5、ios实战开发之仿新浪微博(第五讲:微博数据加载)
6、ios实战开发之仿新浪微博(第六讲:微博数据展示一)
7、ios实战开发之仿新浪微博(第七讲:微博数据展示二)
8、ios实战开发之仿新浪微博(第八讲:微博数据展示三)
9、ios实战开发之仿新浪微博(第九讲:微博功能完善一)
10、ios实战开发之仿新浪微博(第十讲:微博功能完善二)
11、ios实战开发之仿新浪微博(第十一讲:微博功能完善三)
12、ios实战开发之仿新浪微博(小龙虾发布版)

大象装冰箱O 发表于 2014-10-14 00:20:53

今天突然发现了这个非常棒的主页{:soso_e113:}

panzilong 发表于 2014-10-23 20:26:14

大赞这篇神贴!

zj0517 发表于 2014-11-17 11:05:35

持续关注,先下载看看!

yipangzi 发表于 2014-11-19 13:03:05

要是再加上一点教程,就完美了,是好东西

xuguofei2006 发表于 2015-1-5 17:25:59

尽管有点iOS的知识,我还在学习中...

447963200 发表于 2015-3-18 15:00:59

:loveliness:好网站,好贴!加油~

Miul 发表于 2015-6-13 15:28:36

好好学习学习楼主的这套教程,谢谢楼主的分享。

Miul 发表于 2015-6-14 14:21:38

SAAppDelegate中的属性viewController没有用到。

nullptr 发表于 2015-7-17 17:27:44

不错,谢谢楼主贡献
页: [1] 2 3 4
查看完整版本: ios实战开发之仿新浪微博(第一讲:新特性展示)