提交 5700f0a6 编写于 作者: G Gdier

ios: demo app support input URL and QRCode scan after iOS 7

上级 54a38e22
......@@ -9,6 +9,15 @@
/* Begin PBXBuildFile section */
45D57D611A53233200BDD389 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45D57D601A53233200BDD389 /* CoreVideo.framework */; };
45D57D631A53233800BDD389 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45D57D621A53233800BDD389 /* VideoToolbox.framework */; };
55E809E21B143C47003E98A5 /* IJKDemoMainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55E809E11B143C47003E98A5 /* IJKDemoMainViewController.m */; };
55E809E41B143C85003E98A5 /* IJKDemoMainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E809E31B143C85003E98A5 /* IJKDemoMainViewController.xib */; };
55E809E61B145B55003E98A5 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E809E51B145B55003E98A5 /* LaunchScreen.xib */; };
55E809EA1B145BC2003E98A5 /* IJKDemoInputURLViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55E809E81B145BC2003E98A5 /* IJKDemoInputURLViewController.m */; };
55E809EB1B145BC2003E98A5 /* IJKDemoInputURLViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E809E91B145BC2003E98A5 /* IJKDemoInputURLViewController.xib */; };
55E809EE1B146C1E003E98A5 /* IJKQRCodeScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55E809ED1B146C1E003E98A5 /* IJKQRCodeScanViewController.m */; };
55E809F11B146C80003E98A5 /* Barcode.m in Sources */ = {isa = PBXBuildFile; fileRef = 55E809F01B146C80003E98A5 /* Barcode.m */; };
55E809F31B146DE8003E98A5 /* IJKQRCodeScanViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55E809F21B146DE8003E98A5 /* IJKQRCodeScanViewController.xib */; };
55E809F61B1480BC003E98A5 /* IJKDemoHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = 55E809F51B1480BC003E98A5 /* IJKDemoHistory.m */; };
E60E8C2A19EF70BB005B5B6E /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E60E8C2919EF70BB005B5B6E /* CoreMedia.framework */; };
E60FFBE418BF695700825D7F /* libIJKMediaPlayer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E6D74F2E18A5F94B00165BFD /* libIJKMediaPlayer.a */; };
E612EAE517F7E0F800BEE660 /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E612EAE417F7E0F800BEE660 /* MediaPlayer.framework */; };
......@@ -62,6 +71,20 @@
/* Begin PBXFileReference section */
45D57D601A53233200BDD389 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
45D57D621A53233800BDD389 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
55E809E01B143C47003E98A5 /* IJKDemoMainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJKDemoMainViewController.h; sourceTree = "<group>"; };
55E809E11B143C47003E98A5 /* IJKDemoMainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJKDemoMainViewController.m; sourceTree = "<group>"; };
55E809E31B143C85003E98A5 /* IJKDemoMainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IJKDemoMainViewController.xib; sourceTree = "<group>"; };
55E809E51B145B55003E98A5 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = "<group>"; };
55E809E71B145BC2003E98A5 /* IJKDemoInputURLViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJKDemoInputURLViewController.h; sourceTree = "<group>"; };
55E809E81B145BC2003E98A5 /* IJKDemoInputURLViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJKDemoInputURLViewController.m; sourceTree = "<group>"; };
55E809E91B145BC2003E98A5 /* IJKDemoInputURLViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IJKDemoInputURLViewController.xib; sourceTree = "<group>"; };
55E809EC1B146C1E003E98A5 /* IJKQRCodeScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJKQRCodeScanViewController.h; sourceTree = "<group>"; };
55E809ED1B146C1E003E98A5 /* IJKQRCodeScanViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJKQRCodeScanViewController.m; sourceTree = "<group>"; };
55E809EF1B146C80003E98A5 /* Barcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Barcode.h; sourceTree = "<group>"; };
55E809F01B146C80003E98A5 /* Barcode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Barcode.m; sourceTree = "<group>"; };
55E809F21B146DE8003E98A5 /* IJKQRCodeScanViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = IJKQRCodeScanViewController.xib; sourceTree = "<group>"; };
55E809F41B1480BC003E98A5 /* IJKDemoHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IJKDemoHistory.h; sourceTree = "<group>"; };
55E809F51B1480BC003E98A5 /* IJKDemoHistory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IJKDemoHistory.m; sourceTree = "<group>"; };
E60E8C2719EF70A7005B5B6E /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
E60E8C2919EF70BB005B5B6E /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
E612EAE417F7E0F800BEE660 /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; };
......@@ -130,6 +153,8 @@
isa = PBXGroup;
children = (
E63FC27817F032FD003551EB /* IJKCommon.h */,
55E809EF1B146C80003E98A5 /* Barcode.h */,
55E809F01B146C80003E98A5 /* Barcode.m */,
);
name = Misc;
sourceTree = "<group>";
......@@ -212,6 +237,7 @@
E6903F1317EAF70200CFD954 /* Default@2x.png */,
E6903F1517EAF70200CFD954 /* Default-568h@2x.png */,
E6166C9B17EDA4A20006B956 /* IJKMediaDemo-Prefix.pch */,
55E809E51B145B55003E98A5 /* LaunchScreen.xib */,
);
name = "Supporting Files";
sourceTree = "<group>";
......@@ -219,11 +245,22 @@
E6A9B55C17EDA6AC00A1A500 /* View Controllers */ = {
isa = PBXGroup;
children = (
55E809E01B143C47003E98A5 /* IJKDemoMainViewController.h */,
55E809E11B143C47003E98A5 /* IJKDemoMainViewController.m */,
55E809E31B143C85003E98A5 /* IJKDemoMainViewController.xib */,
E6A9B56117EDA72C00A1A500 /* IJKMoviePlayerViewController.h */,
E6A9B56217EDA72C00A1A500 /* IJKMoviePlayerViewController.m */,
E6A9B56317EDA72C00A1A500 /* IJKMoviePlayerViewController.xib */,
E66F8DC917EEDD8B00354D80 /* IJKMediaControl.h */,
E66F8DCA17EEDD8B00354D80 /* IJKMediaControl.m */,
55E809E71B145BC2003E98A5 /* IJKDemoInputURLViewController.h */,
55E809E81B145BC2003E98A5 /* IJKDemoInputURLViewController.m */,
55E809E91B145BC2003E98A5 /* IJKDemoInputURLViewController.xib */,
55E809EC1B146C1E003E98A5 /* IJKQRCodeScanViewController.h */,
55E809ED1B146C1E003E98A5 /* IJKQRCodeScanViewController.m */,
55E809F21B146DE8003E98A5 /* IJKQRCodeScanViewController.xib */,
55E809F41B1480BC003E98A5 /* IJKDemoHistory.h */,
55E809F51B1480BC003E98A5 /* IJKDemoHistory.m */,
);
name = "View Controllers";
sourceTree = "<group>";
......@@ -320,7 +357,11 @@
E66F8DE117EEF73600354D80 /* btn_player_pause.png in Resources */,
E66F8DE217EEF73600354D80 /* btn_player_pause@2x.png in Resources */,
E66F8DE317EEF73600354D80 /* btn_player_play.png in Resources */,
55E809E41B143C85003E98A5 /* IJKDemoMainViewController.xib in Resources */,
55E809F31B146DE8003E98A5 /* IJKQRCodeScanViewController.xib in Resources */,
55E809E61B145B55003E98A5 /* LaunchScreen.xib in Resources */,
E66F8DE417EEF73600354D80 /* btn_player_play@2x.png in Resources */,
55E809EB1B145BC2003E98A5 /* IJKDemoInputURLViewController.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -331,10 +372,15 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
55E809F61B1480BC003E98A5 /* IJKDemoHistory.m in Sources */,
E6903F0C17EAF70200CFD954 /* main.m in Sources */,
55E809E21B143C47003E98A5 /* IJKDemoMainViewController.m in Sources */,
E6903F1017EAF70200CFD954 /* IJKAppDelegate.m in Sources */,
E6A9B56417EDA72C00A1A500 /* IJKMoviePlayerViewController.m in Sources */,
55E809F11B146C80003E98A5 /* Barcode.m in Sources */,
E66F8DCB17EEDD8B00354D80 /* IJKMediaControl.m in Sources */,
55E809EA1B145BC2003E98A5 /* IJKDemoInputURLViewController.m in Sources */,
55E809EE1B146C1E003E98A5 /* IJKQRCodeScanViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
//
// Barcode.h
// featurebuild
//
// Created by Jake Widmer on 10/5/13.
// Copyright (c) 2013 Jake Widmer. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface Barcode : NSObject
+ (Barcode * )processMetadataObject:(AVMetadataMachineReadableCodeObject*) code;
- (NSString *) getBarcodeType;
- (NSString *) getBarcodeData;
- (void) printBarcodeData;
@end
//
// Barcode.m
// featurebuild
//
// Created by Jake Widmer on 10/5/13.
// Copyright (c) 2013 Jake Widmer. All rights reserved.
//
#import "Barcode.h"
@interface Barcode()
@property (nonatomic, strong) AVMetadataMachineReadableCodeObject *metadataObject;
@property (nonatomic, strong) NSString * barcodeType;
@property (nonatomic, strong) NSString * barcodeData;
@property (nonatomic, strong) UIBezierPath *cornersPath;
@property (nonatomic, strong) UIBezierPath *boundingBoxPath;
@end
@implementation Barcode
+ (Barcode * )processMetadataObject: (AVMetadataMachineReadableCodeObject*)code
{
// 1 create the obj
Barcode * barcode=[[Barcode alloc]init];
// 2 store code type and string
barcode.barcodeType = [NSString stringWithString:code.type];
barcode.barcodeData = [NSString stringWithString:code.stringValue];
barcode.metadataObject = code;
// 3 & 4 Create the path joining code's corners
CGMutablePathRef cornersPath = CGPathCreateMutable();
// 5 Make point
CGPoint point;
CGPointMakeWithDictionaryRepresentation(
(CFDictionaryRef)code.corners[0], &point);
// 6 Make path
CGPathMoveToPoint(cornersPath, nil, point.x, point.y);
// 7
for (int i = 1; i < code.corners.count; i++) {
CGPointMakeWithDictionaryRepresentation(
(CFDictionaryRef)code.corners[i], &point);
CGPathAddLineToPoint(cornersPath, nil,
point.x, point.y);
}
// 8 Finish box
CGPathCloseSubpath(cornersPath);
// 9 Set path
barcode.cornersPath =
[UIBezierPath bezierPathWithCGPath:cornersPath];
CGPathRelease(cornersPath);
// Create the path for the code's bounding box
// 10
barcode.boundingBoxPath =
[UIBezierPath bezierPathWithRect:code.bounds];
// 11 return
return barcode;
}
- (NSString *) getBarcodeType{
return self.barcodeType;
}
- (NSString *) getBarcodeData{
return self.barcodeData;
}
- (void) printBarcodeData{
NSLog(@"Barcode of type: %@ and data: %@",self.metadataObject.type, self.barcodeData);
}
@end
......@@ -8,11 +8,9 @@
#import <UIKit/UIKit.h>
@class IJKVideoViewController;
@interface IJKAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) IJKVideoViewController *viewController;
@property (strong, nonatomic) UIViewController *viewController;
@end
......@@ -7,18 +7,21 @@
//
#import "IJKAppDelegate.h"
#import "IJKMoviePlayerViewController.h"
#import "IJKDemoMainViewController.h"
@implementation IJKAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[IJKVideoViewController alloc] initView];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[IJKDemoMainViewController alloc] init]];
self.viewController = navigationController;
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
......
......@@ -10,3 +10,4 @@
#define IOS_OLDER_THAN_6 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] < 6.0 )
#define IOS_NEWER_OR_EQUAL_TO_6 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= 6.0 )
#define IOS_NEWER_OR_EQUAL_TO_7 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= 7.0 )
//
// IJKDemoHistory.h
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface IJKDemoHistoryItem : NSObject <NSCoding>
@property(nonatomic,strong) NSString *title;
@property(nonatomic,strong) NSURL *url;
@end
@interface IJKDemoHistory : NSObject
+ (instancetype)instance;
@property(nonatomic,strong,readonly) NSArray *list;
- (void)removeAtIndex:(NSUInteger)index;
- (void)add:(IJKDemoHistoryItem *)item;
@end
//
// IJKDemoHistory.m
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import "IJKDemoHistory.h"
@implementation IJKDemoHistoryItem
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.url forKey:@"url"];
[aCoder encodeObject:self.title forKey:@"title"];
}
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
self.title = [coder decodeObjectForKey:@"title"];
self.url = [coder decodeObjectForKey:@"url"];
}
return self;
}
@end
@interface IJKDemoHistory ()
@end
@implementation IJKDemoHistory {
NSMutableArray *_list;
}
+ (instancetype)instance {
static IJKDemoHistory *s_obj = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
s_obj = [[IJKDemoHistory alloc] init];
});
return s_obj;
}
- (instancetype)init {
self = [super init];
if (self) {
_list = [NSKeyedUnarchiver unarchiveObjectWithFile:[self dbfilePath]];
if (nil == _list)
_list = [NSMutableArray array];
}
return self;
}
- (NSString *)dbfilePath {
NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask, YES) firstObject];
libraryPath = [libraryPath stringByAppendingPathComponent:@"ijkhistory.plist"];
return libraryPath;
}
- (NSArray *)list {
return _list;
}
- (void)removeAtIndex:(NSUInteger)index {
[_list removeObjectAtIndex:index];
[NSKeyedArchiver archiveRootObject:_list toFile:[self dbfilePath]];
}
- (void)add:(IJKDemoHistoryItem *)item {
__block NSUInteger findIdx = NSNotFound;
[_list enumerateObjectsUsingBlock:^(IJKDemoHistoryItem *enumItem, NSUInteger idx, BOOL *stop) {
if ([enumItem.url isEqual:item.url]) {
findIdx = idx;
*stop = YES;
}
}];
if (NSNotFound != findIdx) {
[_list removeObjectAtIndex:findIdx];
}
[_list insertObject:item atIndex:0];
[NSKeyedArchiver archiveRootObject:_list toFile:[self dbfilePath]];
}
@end
//
// IJKDemoInputURLViewController.h
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface IJKDemoInputURLViewController : UIViewController
@end
//
// IJKDemoInputURLViewController.m
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import "IJKDemoInputURLViewController.h"
#import "IJKMoviePlayerViewController.h"
@interface IJKDemoInputURLViewController () <UITextViewDelegate>
@property(nonatomic,strong) IBOutlet UITextView *textView;
@end
@implementation IJKDemoInputURLViewController
- (instancetype)init {
self = [super init];
if (self) {
self.title = @"Input URL";
[self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"Play" style:UIBarButtonItemStyleDone target:self action:@selector(onClickPlayButton)]];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)onClickPlayButton {
NSURL *url = [NSURL URLWithString:self.textView.text];
NSString *scheme = [[url scheme] lowercaseString];
if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) {
[IJKVideoViewController presentFromViewController:self withTitle:[NSString stringWithFormat:@"URL: %@", url] URL:url completion:^{
[self.navigationController popViewControllerAnimated:NO];
}];
}
}
- (void)textViewDidEndEditing:(UITextView *)textView {
[self onClickPlayButton];
}
@end
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7531" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7520"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="IJKDemoInputURLViewController">
<connections>
<outlet property="textView" destination="umQ-0P-p2z" id="uhq-2S-7Pb"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="umQ-0P-p2z">
<rect key="frame" x="8" y="8" width="584" height="584"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="URL" returnKeyType="go" enablesReturnKeyAutomatically="YES"/>
<connections>
<outlet property="delegate" destination="-1" id="qOq-wA-HFo"/>
</connections>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="umQ-0P-p2z" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="8" id="2zf-bJ-LK8"/>
<constraint firstAttribute="bottom" secondItem="umQ-0P-p2z" secondAttribute="bottom" constant="8" id="ENy-rQ-9YF"/>
<constraint firstAttribute="trailing" secondItem="umQ-0P-p2z" secondAttribute="trailing" constant="8" id="N7V-Kf-ayr"/>
<constraint firstAttribute="bottom" secondItem="umQ-0P-p2z" secondAttribute="bottom" id="UXz-GP-DN9"/>
<constraint firstAttribute="trailing" secondItem="umQ-0P-p2z" secondAttribute="trailing" id="YgQ-xw-l1l"/>
<constraint firstItem="umQ-0P-p2z" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="8" id="gAV-yS-4Tt"/>
<constraint firstItem="umQ-0P-p2z" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="vah-gr-VK9"/>
<constraint firstItem="umQ-0P-p2z" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="wZS-sX-ly5"/>
</constraints>
<variation key="default">
<mask key="constraints">
<exclude reference="UXz-GP-DN9"/>
<exclude reference="YgQ-xw-l1l"/>
<exclude reference="vah-gr-VK9"/>
<exclude reference="wZS-sX-ly5"/>
</mask>
</variation>
</view>
</objects>
</document>
//
// IJKDemoMainViewController.h
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface IJKDemoMainViewController : UIViewController
@end
//
// IJKDemoMainViewController.m
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import "IJKDemoMainViewController.h"
#import "IJKDemoInputURLViewController.h"
#import "IJKQRCodeScanViewController.h"
#import "IJKCommon.h"
#import "IJKDemoHistory.h"
#import "IJKMoviePlayerViewController.h"
@interface IJKDemoMainViewController () <UITableViewDataSource, UITableViewDelegate>
@property(nonatomic,strong) IBOutlet UITableView *tableView;
@property(nonatomic,strong) NSArray *tableViewCellTitles;
@property(nonatomic,strong) NSArray *historyList;
@end
@implementation IJKDemoMainViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Main";
self.tableViewCellTitles = @[
@"Local Folder",
@"Input URL",
@"Scan QRCode",
];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.historyList = [[IJKDemoHistory instance] list];
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
switch (section) {
case 0:
return @"Open from";
case 1:
return @"History";
default:
return nil;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch (section) {
case 0:
if (IOS_NEWER_OR_EQUAL_TO_7) {
return self.tableViewCellTitles.count;
} else {
return self.tableViewCellTitles.count - 1;
}
case 1:
return self.historyList.count;
default:
return 0;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"abc"];
if (nil == cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"abc"];
}
switch (indexPath.section) {
case 0:
cell.textLabel.text = self.tableViewCellTitles[indexPath.row];
break;
case 1:
cell.textLabel.text = [self.historyList[indexPath.row] title];
break;
default:
break;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
switch (indexPath.section) {
case 0: {
switch (indexPath.row) {
case 0:
[[[UIAlertView alloc] initWithTitle:nil message:@"TODO" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil] show];
break;
case 1:
[self.navigationController pushViewController:[[IJKDemoInputURLViewController alloc] init] animated:YES];
break;
case 2:
[self.navigationController pushViewController:[[IJKQRCodeScanViewController alloc] init] animated:YES];
break;
default:
break;
}
} break;
case 1: {
IJKDemoHistoryItem *historyItem = self.historyList[indexPath.row];
[IJKVideoViewController presentFromViewController:self withTitle:historyItem.title URL:historyItem.url completion:^{
[self.navigationController popViewControllerAnimated:NO];
}];
} break;
default:
break;
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return (indexPath.section == 1);
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1) {
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 1 && editingStyle == UITableViewCellEditingStyleDelete) {
[[IJKDemoHistory instance] removeAtIndex:indexPath.row];
self.historyList = [[IJKDemoHistory instance] list];
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
@end
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7531" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7520"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="IJKDemoMainViewController">
<connections>
<outlet property="tableView" destination="hFv-Sg-rxl" id="OuB-AJ-cvM"/>
<outlet property="view" destination="iN0-l3-epB" id="d8B-6e-hY8"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="hFv-Sg-rxl">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<connections>
<outlet property="dataSource" destination="-1" id="Sct-ml-94e"/>
<outlet property="delegate" destination="-1" id="6Si-jf-dml"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="hFv-Sg-rxl" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="44f-8U-Nl9"/>
<constraint firstAttribute="bottom" secondItem="hFv-Sg-rxl" secondAttribute="bottom" id="JWM-jK-2fA"/>
<constraint firstItem="hFv-Sg-rxl" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="MYB-hY-tK5"/>
<constraint firstAttribute="trailing" secondItem="hFv-Sg-rxl" secondAttribute="trailing" id="s3E-4P-8xx"/>
</constraints>
</view>
</objects>
</document>
......@@ -24,6 +24,10 @@
<string>102</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
......
......@@ -12,9 +12,12 @@
@interface IJKVideoViewController : UIViewController
@property(atomic,strong) NSURL *url;
@property(atomic, retain) id<IJKMediaPlayback> player;
- (id)initView;
- (id)initWithURL:(NSURL *)url;
+ (void)presentFromViewController:(UIViewController *)viewController withTitle:(NSString *)title URL:(NSURL *)url completion:(void(^)())completion;
- (IBAction)onClickMediaControl:(id)sender;
- (IBAction)onClickOverlay:(id)sender;
......
......@@ -10,16 +10,30 @@
#import "IJKMediaControl.h"
#import "IJKCommon.h"
#import "IJKMediaPlayer/IJKMediaPlayer.h"
#import "IJKDemoHistory.h"
@implementation IJKVideoViewController
- (id)initView
- (void)dealloc
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return [self initWithNibName:@"IJKMoviePlayerViewController" bundle:nil];
} else {
return [self initWithNibName:@"IJKMoviePlayerViewController" bundle:nil];
}
+ (void)presentFromViewController:(UIViewController *)viewController withTitle:(NSString *)title URL:(NSURL *)url completion:(void (^)())completion {
IJKDemoHistoryItem *historyItem = [[IJKDemoHistoryItem alloc] init];
historyItem.title = title;
historyItem.url = url;
[[IJKDemoHistory instance] add:historyItem];
[viewController presentViewController:[[IJKVideoViewController alloc] initWithURL:url] animated:YES completion:completion];
}
- (instancetype)initWithURL:(NSURL *)url {
self = [self initWithNibName:@"IJKMoviePlayerViewController" bundle:nil];
if (self) {
self.url = url;
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
......@@ -36,13 +50,11 @@
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];
NSURL *theMovieURL = [NSURL URLWithString:@"http://vhotwsh.video.qq.com/flv/32/146/r0015d10iwu.p203.1.mp4?vkey=68023055CEC9CC9E1D988B0E71E4B58C38B0374F1CB9805F4A1901D8E87B42137DD9680CF88D3685C3A59F030BAE55AA2E7238551DCB6BFF&fmt=sd&type=mp4"];
// [[UIApplication sharedApplication] setStatusBarHidden:YES];
// [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];
[IJKFFMoviePlayerController setLogReport:YES];
self.player = [[IJKFFMoviePlayerController alloc] initWithContentURL:theMovieURL withOptions:nil];
self.player = [[IJKFFMoviePlayerController alloc] initWithContentURL:self.url withOptions:nil];
self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
self.player.view.frame = self.view.bounds;
......@@ -51,15 +63,20 @@
[self.view addSubview:self.mediaControl];
self.mediaControl.delegatePlayer = self.player;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self installMovieNotificationObservers];
[self.player prepareToPlay];
[self.player play];
}
- (void)dealloc
{
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.player shutdown];
[self removeMovieNotificationObservers];
}
......@@ -97,7 +114,9 @@
- (IBAction)onClickBack:(id)sender
{
exit(0);
if (self.presentingViewController) {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
}
- (IBAction)onClickPlay:(id)sender
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="5053" systemVersion="12F45" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7531" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1536" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7520"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="IJKVideoViewController">
......@@ -15,7 +15,8 @@
<view contentMode="scaleToFill" id="1">
<rect key="frame" x="0.0" y="0.0" width="480" height="320"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<color key="backgroundColor" cocoaTouchSystemColor="scrollViewTexturedBackgroundColor"/>
<nil key="simulatedStatusBarMetrics"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
</view>
......@@ -121,6 +122,7 @@
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
......@@ -143,4 +145,9 @@
<image name="player_bottom_control_bg.png" width="400" height="100"/>
<image name="player_top_control_bg.png" width="1" height="44"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>
//
// IJKQRCodeScanViewController.h
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface IJKQRCodeScanViewController : UIViewController
@end
//
// IJKQRCodeScanViewController.m
// IJKMediaDemo
//
// Created by Gdier on 5/26/15.
// Copyright (c) 2015 bilibili. All rights reserved.
//
#import "IJKQRCodeScanViewController.h"
#import "IJKMoviePlayerViewController.h"
#import "Barcode.h"
#import <AVFoundation/AVFoundation.h>
@interface IJKQRCodeScanViewController () <AVCaptureMetadataOutputObjectsDelegate>
@property (weak, nonatomic) IBOutlet UIView *previewView;
@property (strong, nonatomic) NSMutableArray * allowedBarcodeTypes;
//@property (strong, nonatomic) SettingsViewController * settingsVC;
@end
@implementation IJKQRCodeScanViewController {
AVCaptureSession *_captureSession;
AVCaptureDevice *_videoDevice;
AVCaptureDeviceInput *_videoInput;
AVCaptureVideoPreviewLayer *_previewLayer;
BOOL _running;
AVCaptureMetadataOutput *_metadataOutput;
}
- (instancetype)init {
self = [super init];
if (self) {
self.title = @"Scan QRCode";
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupCaptureSession];
_previewLayer.frame = _previewView.bounds;
[_previewView.layer addSublayer:_previewLayer];
// listen for going into the background and stop the session
// set default allowed barcode types, remove types via setings menu if you don't want them to be able to be scanned
self.allowedBarcodeTypes = [NSMutableArray new];
[self.allowedBarcodeTypes addObject:@"org.iso.QRCode"];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
_previewLayer.frame = _previewView.bounds;
[self setupCaptureOrientation];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self startRunning];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self stopRunning];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark - AV capture methods
- (void)setupCaptureSession {
if (_captureSession) {
return;
}
_videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (!_videoDevice) {
return;
}
_captureSession = [[AVCaptureSession alloc] init];
_videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:_videoDevice error:nil];
if ([_captureSession canAddInput:_videoInput]) {
[_captureSession addInput:_videoInput];
}
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
// capture and process the metadata
_metadataOutput = [[AVCaptureMetadataOutput alloc] init];
[_metadataOutput setMetadataObjectsDelegate:self
queue:dispatch_get_main_queue()];
if ([_captureSession canAddOutput:_metadataOutput]) {
[_captureSession addOutput:_metadataOutput];
}
}
- (void)setupCaptureOrientation {
if([_previewLayer.connection isVideoOrientationSupported]) {
AVCaptureVideoOrientation orientation;
switch ([[UIApplication sharedApplication] statusBarOrientation]) {
case UIInterfaceOrientationLandscapeLeft:
orientation = AVCaptureVideoOrientationLandscapeLeft;
break;
case UIInterfaceOrientationLandscapeRight:
orientation = AVCaptureVideoOrientationLandscapeRight;
break;
default:
orientation = AVCaptureVideoOrientationLandscapeLeft;
break;
}
[_previewLayer.connection setVideoOrientation:orientation];
}
}
- (void)startRunning {
if (_running) return;
[_captureSession startRunning];
_metadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];//_metadataOutput.availableMetadataObjectTypes;
_running = YES;
}
- (void)stopRunning {
if (!_running) return;
[_captureSession stopRunning];
_running = NO;
}
- (void)applicationWillEnterForeground:(NSNotification*)note {
[self startRunning];
}
- (void)applicationDidEnterBackground:(NSNotification*)note {
[self stopRunning];
}
#pragma mark - Delegate functions
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputMetadataObjects:(NSArray *)metadataObjects
fromConnection:(AVCaptureConnection *)connection {
[metadataObjects enumerateObjectsUsingBlock:^(AVMetadataObject *obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {
AVMetadataMachineReadableCodeObject *code = (AVMetadataMachineReadableCodeObject *) [_previewLayer transformedMetadataObjectForMetadataObject:obj];
Barcode * barcode = [Barcode processMetadataObject:code];
for(NSString * str in self.allowedBarcodeTypes) {
if([barcode.getBarcodeType isEqualToString:str]) {
[self validBarcodeFound:barcode];
return;
}
}
}
}];
}
- (void) validBarcodeFound:(Barcode *)barcode {
[self stopRunning];
[self showBarcodeAlert:barcode];
}
- (void) showBarcodeAlert:(Barcode *)barcode {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:nil
message:[barcode getBarcodeData]
delegate:self
cancelButtonTitle:@"Scan Again"
otherButtonTitles:@"Play", nil];
[message show];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if(buttonIndex == alertView.cancelButtonIndex) {
[self startRunning];
} else {
NSURL *url = [NSURL URLWithString:alertView.message];
[IJKVideoViewController presentFromViewController:self withTitle:[NSString stringWithFormat:@"URL: %@", url] URL:url completion:^{
[self.navigationController popViewControllerAnimated:NO];
}];
}
}
@end
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7531" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7520"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="IJKQRCodeScanViewController">
<connections>
<outlet property="previewView" destination="iN0-l3-epB" id="hed-3u-VkP"/>
<outlet property="view" destination="iN0-l3-epB" id="jd3-Hf-Ktc"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
</objects>
</document>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7531" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7520"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 bilibili. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
<variation key="widthClass=compact">
<fontDescription key="fontDescription" type="system" pointSize="11"/>
</variation>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="IJKMediaDemo" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="Kid-kn-2rF"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="404" y="445"/>
</view>
</objects>
</document>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册