0%

参考:

  • Quartz2D 编程指南(一)概览、图形上下文、路径、颜色与颜色空间
  • Quartz2D 编程指南(二)变换、图案、阴影
  • Quartz2D 编程指南(三)渐变、透明层 、数据管理
  • Quartz2D 编程指南(四)位图与图像遮罩、CoreGraphics 绘制 Layer

参考

  • 官方文档:iOS 视图控制器编程指南
  • 翻译:iOS 视图控制器编程指南(View Controller Programming Guide for iOS)
  • 翻译:iOS 视图控制器编程指南(一)—— 视图控制器的作用(The Role of View Controllers)
  • 翻译:iOS 视图控制器编程指南(二)—— 视图控制器层级结构(The View Controller Hierarchy)
  • 翻译:iOS 视图控制器编程指南(三)—— 设计技巧(Design Tips)
  • 翻译:iOS 视图控制器编程指南(四)—— 定义子类(Defining Your Subclass)
  • 翻译:iOS 视图控制器编程指南(五)—— 实现容器视图控制器(Implementing a Container View Controller)
  • 翻译:iOS 视图控制器编程指南(六)—— 支持可访问性(Supporting Accessibility)
  • 翻译:iOS 视图控制器编程指南(七)—— 保存和恢复状态(Preserving and Restoring State)
  • 翻译:iOS 视图控制器编程指南(八)——Present 视图控制器(Presenting a View Controller)
  • 翻译:iOS 视图控制器编程指南(九)—— 使用 segue(Using Segues)
  • 翻译:iOS 视图控制器编程指南(十)—— 自定义过渡动画 (Customizing the Transition Animations)
  • 翻译:iOS 视图控制器编程指南(十一)—— 创建自定义 present(Creating Custom Presentations)
  • 翻译:iOS 视图控制器编程指南(十二)—— 自适应 model(The Adaptive Model)
  • 翻译:iOS 视图控制器编程指南(十三)—— 创建自适应界面(Building an Adaptive Interface)

UIWindow

最常用的方法:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 1.创建 UIWindow 实例。
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // 2.指定 UIWindow 对象的根视图控制器。
    ViewController *viewController = [[ViewController alloc] init];
    self.window.rootViewController = viewController;

    // 3.设置背景色。
    self.window.backgroundColor = [UIColor whiteColor];

    // 4.设置 UIWindow 实例为主窗口并使其可见。
    [self.window makeKeyAndVisible];

    return YES;
}
  • UIWindow 对象提供了一个方法 setRootViewController 将视图控制器的视图层次结构加入应用窗口。当程序将某个视图控制器设置为 UIWindow 对象的 rootViewControl 时,UIWindow 对象会将该视图控制器的 view 作为子视图加入窗口,同时负责维护 viewController 和 view 对应的生命周期。此外,还会自动调整 view 的大小,将其设置为与窗口的大小相同。
  • rootViewControl 的 view 需要在应用启动完毕之后就显示,所以 UIWindow 对象会在设置完 rootViewControl 后立刻加载其 view。
阅读全文 »

UINavigationController

UINavigationController 类实现了一个用于管理分层内容导航的专用视图控制器。 该导航界面可以有效地呈现您的数据,并使用户更容易浏览该内容。 您通常按照原样使用此类,但您也可以使用子类来自定义类的行为。

预览

导航界面呈现的屏幕通常会模拟您的数据层次结构。 在层次结构的每个级别中,您提供一个适当的屏幕(由自定义视图控制器管理)来显示该级别的内容。 图 1 显示了 iOS 模拟器中 “设置” 应用程序提供的导航界面的示例。 第一个屏幕向用户显示包含首选项的应用程序列表。 选择应用程序会显示该应用程序的各个设置和设置组。 选择组会产生更多设置等等。 除了根视图之外,导航控制器提供一个后退按钮,以允许用户返回到上一层次结构。

图 1

阅读全文 »

KeyChain 推荐使用这个第三方开源库: [soffes/SAMKeychain] (https://github.com/soffes/SAMKeychain) ⭐️⭐️⭐️ 5000+

新建 KeyChain 类,用于实现向 keyChain 存储、读取和修改用户名密码。代码如下:

KeyChain.h 文件

#import <Foundation/Foundation.h>
#import <Security/Security.h>

@interface KeyChain : NSObject

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service;

// save username and password to keychain
+ (void)save:(NSString *)service data:(id)data;

// load username and password from keychain
+ (id)load:(NSString *)service;

// delete username and password from keychain
+ (void)delete:(NSString *)serviece;

@end

KeyChain.m 文件

#import "KeyChain.h"

@implementation KeyChain

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (id)kSecClassGenericPassword,(id)kSecClass,
            service, (id)kSecAttrService,
            service, (id)kSecAttrAccount,
            (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
            nil];
}

#pragma mark 写入
+ (void)save:(NSString *)service data:(id)data {
    //Get search dictionary
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Delete old item before add new item
    SecItemDelete((CFDictionaryRef)keychainQuery);
    //Add new object to search dictionary(Attention:the data format)
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
    //Add item to keychain with the search dictionary
    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}

#pragma mark 读取
+ (id)load:(NSString *)service {
    id ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Configure the search setting
    //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
    [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
        } @catch (NSException *e) {
            NSLog(@"Unarchive of %@ failed: %@", service, e);
        } @finally {
        }
    }
    if (keyData)
        CFRelease(keyData);
    return ret;
}

#pragma mark 删除
+ (void)delete:(NSString *)service {
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    SecItemDelete((CFDictionaryRef)keychainQuery);
}

@end

PasswordManager

#import <Foundation/Foundation.h>

/**
 管理用户密码
 */
@interface PasswordManger : NSObject

+ (void)savePassword:(NSString *)password;

+ (NSString *)loadPassword;

+ (void)deletePassword;

@end

#import "PasswordManger.h"
#import "AppKeyChain.h"

static NSString *const PASSWORD = @"com.CompanyName.ProjectName.password";

@implementation PasswordManger

+ (void)savePassword:(NSString *)password {
    [AppKeyChain saveData:password forKey:PASSWORD];
}

+ (NSString *)loadPassword {
    NSString *password = (NSString *)[AppKeyChain loadForKey:PASSWORD];
    return password;
}

+ (void)deletePassword {
    [AppKeyChain deleteKey:PASSWORD];
}

@end

  • GitHub 地址:PageMenu
  • **star:**3800+

🎉 🎉 🎉 Surprise ! I’m back! 本期给大家带来的第三方框架是一个非常常用的导航框架 —— 分页菜单 PageMenu。该框架同时支持 Swift 和 Objective-C,使用起来也是极其方便,下面一起来跟我看看吧!

PageMenuHeader

阅读全文 »

目录结构

  • PageControllerViewController

    PageControllerViewController 的父类是 UIViewController,它是一个容器视图控制器,用于处理两个子视图之间的切换

  • FirstSubViewController

    FirstSubViewController 的父类也是 UIViewController,褐色子视图。

  • SecondSubViewController

    SecondSubViewController 的父类也是 UIViewController,紫色子视图。

阅读全文 »

对象继承关系

UIButton 类本身定义继承 UIControl ,描述了在 iOS 上所有用户界面控件的常见基本行为。反过来, UIControl 类继承 UIView ,给在屏幕显示的对象提供常用功能。UIView 继承于 UIResponder,允许它响应用户输 入、手势。最后,也是最重要的,UIResponder 继承 NSObject,图 1-3 所示。

image

阅读全文 »