From f387ad2d681c622a2b66d82e653d7fff72849ea6 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 29 Aug 2013 14:56:18 -0400 Subject: [PATCH 01/39] Added podspec --- Chameleon.podspec | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Chameleon.podspec diff --git a/Chameleon.podspec b/Chameleon.podspec new file mode 100644 index 00000000..0a6fd037 --- /dev/null +++ b/Chameleon.podspec @@ -0,0 +1,53 @@ +Pod::Spec.new do |s| + s.name = "Chameleon" + s.version = "0.0.2" + s.summary = "Chameleon is a port of Apple's UIKit (and some minimal related frameworks) to Mac OS X." + s.description = "Chameleon is a port of Apple's UIKit (and some minimal related frameworks) to Mac OS X. It is meant to be as much of a drop-in replacement for the real UIKit as possible. It also adapts some iOS user interface conventions to the Mac (such as UIAlertView being represented by NSAlert) so that apps built using Chameleon have as much chance as possible of feeling at home on the desktop with relatively little porting effort." + s.homepage = "http://chameleonproject.org/" + s.author = { "Sean Heber" => "sean@iconfactory.com" } + s.source = { :git => "https://github.com/michaelmelanson/Chameleon.git" } + s.license = { :type => 'Modified BSD License' } + s.platform = :osx, '10.6' + s.frameworks = 'IOKit', 'QuartzCore', 'SystemConfiguration', 'AppKit', 'Foundation', 'QTKit', 'WebKit' + + s.prefix_header_contents = "// If ARC is not enabled, declare empty ARC directives to supress compiler errors + #ifndef __has_feature + #define __has_feature(x) 0 // Compatibility with non-clang compilers. + #endif + + #if !__has_feature(objc_arc) + #define __unsafe_unretained + #define __bridge + #endif" + + s.subspec 'UIKit' do |sb| + sb.source_files = 'UIKit/Classes/*.{h,m}' + sb.resources = "UIKit/Resources/*.png" + sb.header_dir = 'UIKit' + end + + s.subspec 'StoreKit' do |sb| + sb.source_files = 'StoreKit/Classes/*.{h,m}' + sb.header_dir = 'StoreKit' + end + + s.subspec 'AVFoundation' do |sb| + sb.source_files = 'AVFoundation/Classes/*.{h,m}' + sb.header_dir = 'AVFoundation' + end + + s.subspec 'AssetsLibrary' do |sb| + sb.source_files = 'AssetsLibrary/Classes/*.{h,m}' + sb.header_dir = 'AssetsLibrary' + end + + s.subspec 'MediaPlayer' do |sb| + sb.source_files = 'MediaPlayer/Classes/*.{h,m}' + sb.header_dir = 'MediaPlayer' + end + + s.subspec 'MessageUI' do |sb| + sb.source_files = 'MessageUI/*.{h,m}', 'MessageUI/Classes/*.{h,m}' + sb.header_dir = 'MessageUI' + end +end From 6401494c28f8c51c51f2e96c4dd646ca7c624db3 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 29 Aug 2013 15:13:40 -0400 Subject: [PATCH 02/39] Use [UIImage imageNamed:] to load images. This is probably a bad idea, but I have no idea why yet. --- UIKit/Classes/UIImage+UIPrivate.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/UIKit/Classes/UIImage+UIPrivate.m b/UIKit/Classes/UIImage+UIPrivate.m index dfade4f5..7fcd6a9a 100644 --- a/UIKit/Classes/UIImage+UIPrivate.m +++ b/UIKit/Classes/UIImage+UIPrivate.m @@ -60,9 +60,7 @@ + (UIImage *)_frameworkImageWithName:(NSString *)name leftCapWidth:(NSUInteger)l UIImage *image = [self _cachedImageForName:name]; if (!image) { - NSBundle *frameworkBundle = [NSBundle bundleWithIdentifier:@"org.chameleonproject.UIKit"]; - NSString *frameworkFile = [[frameworkBundle resourcePath] stringByAppendingPathComponent:name]; - image = [[self imageWithContentsOfFile:frameworkFile] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight]; + image = [[UIImage imageNamed:name] stretchableImageWithLeftCapWidth:leftCapWidth topCapHeight:topCapHeight]; [self _cacheImage:image forName:name]; } From aeaf1d7a3e86ec3271596df2f95b3694bb30cfd0 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 29 Aug 2013 16:05:20 -0400 Subject: [PATCH 03/39] Set the preferences to enable offline cache and developer extras. This should be refactored into a setter so these values aren't hard-coded. --- UIKit/Classes/UIWebView.m | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/UIKit/Classes/UIWebView.m b/UIKit/Classes/UIWebView.m index df9da91c..c825f8bf 100644 --- a/UIKit/Classes/UIWebView.m +++ b/UIKit/Classes/UIWebView.m @@ -31,6 +31,15 @@ #import "UIViewAdapter.h" #import +@interface WebPreferences (WebPreferencesPrivate) +- (void)_setLocalStorageDatabasePath:(NSString *)path; +- (void) setLocalStorageEnabled: (BOOL) localStorageEnabled; +- (void) setDatabasesEnabled:(BOOL)databasesEnabled; +- (void) setDeveloperExtrasEnabled:(BOOL)developerExtrasEnabled; +- (void) setWebGLEnabled:(BOOL)webGLEnabled; +- (void) setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled; +@end + @implementation UIWebView @synthesize request=_request, delegate=_delegate, dataDetectorTypes=_dataDetectorTypes, scalesPageToFit=_scalesPageToFit; @@ -45,6 +54,12 @@ - (id)initWithFrame:(CGRect)frame [_webView setFrameLoadDelegate:self]; [_webView setUIDelegate:self]; [_webView setDrawsBackground:NO]; + + WebPreferences *preferences = [WebPreferences standardPreferences]; + [preferences setOfflineWebApplicationCacheEnabled:YES]; + [preferences setDeveloperExtrasEnabled:YES]; + + [_webView setPreferences:preferences]; _webViewAdapter = [[UIViewAdapter alloc] initWithFrame:self.bounds]; _webViewAdapter.NSView = _webView; From b3c007814dfca1dfc2c22735bd371f6a1361a240 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 10 Sep 2013 10:10:07 -0400 Subject: [PATCH 04/39] Hack to get rid of 'drifting' caused by rounding bias in UIView autoresizing. See BigZaphod/Chameleon#82. --- UIKit/Classes/UIView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index ecdc0d27..13b81b40 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -646,7 +646,7 @@ - (void)_superviewSizeDidChangeFrom:(CGSize)oldSize to:(CGSize)newSize } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth)) { frame.size.width = floorf(frame.size.width + (frame.size.width / (oldSize.width - frame.origin.x) * delta.width)); } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin)) { - frame.origin.x = floorf(frame.origin.x + (delta.width / 2.f)); + frame.origin.x = /*floorf*/(frame.origin.x + (delta.width / 2.f)); } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleWidth)) { frame.size.width = floorf(frame.size.width + delta.width); } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleLeftMargin)) { From f3cd5c573c9d66110a587976adf8cc2f6d775734 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 10 Sep 2013 10:34:22 -0400 Subject: [PATCH 05/39] Use floats for autoresizing and round to integers for the CGLayer's frame. --- UIKit/Classes/UIView.h | 1 + UIKit/Classes/UIView.m | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/UIKit/Classes/UIView.h b/UIKit/Classes/UIView.h index 655518bc..6a3e401e 100644 --- a/UIKit/Classes/UIView.h +++ b/UIKit/Classes/UIView.h @@ -110,6 +110,7 @@ typedef NSUInteger UIViewAnimationOptions; BOOL _autoresizesSubviews; BOOL _userInteractionEnabled; CALayer *_layer; + CGRect _frame; NSInteger _tag; UIViewContentMode _contentMode; UIColor *_backgroundColor; diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index 13b81b40..0eaa31f5 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -88,6 +88,8 @@ - (id)initWithFrame:(CGRect)theFrame _subviews = [[NSMutableSet alloc] init]; _gestureRecognizers = [[NSMutableSet alloc] init]; + _frame = CGRectZero; + _layer = [[[isa layerClass] alloc] init]; _layer.delegate = self; _layer.layoutManager = [UIViewLayoutManager layoutManager]; @@ -684,14 +686,17 @@ + (NSSet *)keyPathsForValuesAffectingFrame - (CGRect)frame { - return _layer.frame; + return _frame; } - (void)setFrame:(CGRect)newFrame { - if (!CGRectEqualToRect(newFrame,_layer.frame)) { + _frame = newFrame; + + if (!CGRectEqualToRect(CGRectIntegral(newFrame),CGRectIntegral(_layer.frame))) { CGRect oldBounds = _layer.bounds; - _layer.frame = newFrame; + CGRect roundedFrame = CGRectIntegral(_frame); + _layer.frame = roundedFrame; [self _boundsDidChangeFrom:oldBounds to:_layer.bounds]; [[NSNotificationCenter defaultCenter] postNotificationName:UIViewFrameDidChangeNotification object:self]; } From bb827ea2e961124cca07cb1fa140525e5140a038 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 10 Sep 2013 10:34:22 -0400 Subject: [PATCH 06/39] Use floats for autoresizing and round to integers for the CGLayer's frame. --- UIKit/Classes/UIView.h | 1 + UIKit/Classes/UIView.m | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/UIKit/Classes/UIView.h b/UIKit/Classes/UIView.h index b698d6d9..6c206125 100644 --- a/UIKit/Classes/UIView.h +++ b/UIKit/Classes/UIView.h @@ -107,6 +107,7 @@ typedef NSUInteger UIViewAnimationOptions; BOOL _autoresizesSubviews; BOOL _userInteractionEnabled; CALayer *_layer; + CGRect _frame; NSInteger _tag; UIViewContentMode _contentMode; UIColor *_backgroundColor; diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index ecdc0d27..e49bb203 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -88,6 +88,8 @@ - (id)initWithFrame:(CGRect)theFrame _subviews = [[NSMutableSet alloc] init]; _gestureRecognizers = [[NSMutableSet alloc] init]; + _frame = CGRectZero; + _layer = [[[isa layerClass] alloc] init]; _layer.delegate = self; _layer.layoutManager = [UIViewLayoutManager layoutManager]; @@ -684,14 +686,17 @@ + (NSSet *)keyPathsForValuesAffectingFrame - (CGRect)frame { - return _layer.frame; + return _frame; } - (void)setFrame:(CGRect)newFrame { - if (!CGRectEqualToRect(newFrame,_layer.frame)) { + _frame = newFrame; + + if (!CGRectEqualToRect(CGRectIntegral(newFrame),CGRectIntegral(_layer.frame))) { CGRect oldBounds = _layer.bounds; - _layer.frame = newFrame; + CGRect roundedFrame = CGRectIntegral(_frame); + _layer.frame = roundedFrame; [self _boundsDidChangeFrom:oldBounds to:_layer.bounds]; [[NSNotificationCenter defaultCenter] postNotificationName:UIViewFrameDidChangeNotification object:self]; } From 65aa344fb0f60c41ce8f26670fa5121cd92ddd22 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 10 Sep 2013 11:05:37 -0400 Subject: [PATCH 07/39] Eliminate rounding using floorf from all autoresizing calculations. --- UIKit/Classes/UIView.m | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index e49bb203..1587db25 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -620,41 +620,41 @@ - (void)_superviewSizeDidChangeFrom:(CGSize)oldSize to:(CGSize)newSize */ if (hasAutoresizingFor(UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin)) { - frame.origin.y = floorf(frame.origin.y + (frame.origin.y / oldSize.height * delta.height)); - frame.size.height = floorf(frame.size.height + (frame.size.height / oldSize.height * delta.height)); + frame.origin.y += frame.origin.y / oldSize.height * delta.height; + frame.size.height += frame.size.height / oldSize.height * delta.height; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight)) { const CGFloat t = frame.origin.y + frame.size.height; - frame.origin.y = floorf(frame.origin.y + (frame.origin.y / t * delta.height)); - frame.size.height = floorf(frame.size.height + (frame.size.height / t * delta.height)); + frame.origin.y += frame.origin.y / t * delta.height; + frame.size.height += frame.size.height / t * delta.height; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight)) { - frame.size.height = floorf(frame.size.height + (frame.size.height / (oldSize.height - frame.origin.y) * delta.height)); + frame.size.height += frame.size.height / (oldSize.height - frame.origin.y) * delta.height; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin)) { - frame.origin.y = floorf(frame.origin.y + (delta.height / 2.f)); + frame.origin.y += delta.height / 2.f; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleHeight)) { - frame.size.height = floorf(frame.size.height + delta.height); + frame.size.height += delta.height; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleTopMargin)) { - frame.origin.y = floorf(frame.origin.y + delta.height); + frame.origin.y += delta.height; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleBottomMargin)) { - frame.origin.y = floorf(frame.origin.y); + // nothing required } if (hasAutoresizingFor(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin)) { - frame.origin.x = floorf(frame.origin.x + (frame.origin.x / oldSize.width * delta.width)); - frame.size.width = floorf(frame.size.width + (frame.size.width / oldSize.width * delta.width)); + frame.origin.x += frame.origin.x / oldSize.width * delta.width; + frame.size.width += frame.size.width / oldSize.width * delta.width; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth)) { const CGFloat t = frame.origin.x + frame.size.width; - frame.origin.x = floorf(frame.origin.x + (frame.origin.x / t * delta.width)); - frame.size.width = floorf(frame.size.width + (frame.size.width / t * delta.width)); + frame.origin.x += frame.origin.x / t * delta.width; + frame.size.width += frame.size.width / t * delta.width; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth)) { - frame.size.width = floorf(frame.size.width + (frame.size.width / (oldSize.width - frame.origin.x) * delta.width)); + frame.size.width += frame.size.width / (oldSize.width - frame.origin.x) * delta.width; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin)) { - frame.origin.x = floorf(frame.origin.x + (delta.width / 2.f)); + frame.origin.x += delta.width / 2.f; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleWidth)) { - frame.size.width = floorf(frame.size.width + delta.width); + frame.size.width += delta.width; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleLeftMargin)) { - frame.origin.x = floorf(frame.origin.x + delta.width); + frame.origin.x += delta.width; } else if (hasAutoresizingFor(UIViewAutoresizingFlexibleRightMargin)) { - frame.origin.x = floorf(frame.origin.x); + // nothing required } self.frame = frame; From 67a7bfe099d7c12224f3949ff9461bd23efb1310 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 09:21:49 -0500 Subject: [PATCH 08/39] =?UTF-8?q?Don=E2=80=99t=20flip=20geometry=20in=20UI?= =?UTF-8?q?ViewAdapters.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes an issue with UIWebView where its contents would be flipped vertically. --- UIKit/Classes/UIViewAdapter.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIKit/Classes/UIViewAdapter.m b/UIKit/Classes/UIViewAdapter.m index 6e05ce87..242a6872 100644 --- a/UIKit/Classes/UIViewAdapter.m +++ b/UIKit/Classes/UIViewAdapter.m @@ -113,7 +113,7 @@ - (void)_updateLayers CALayer *clipLayer = [_clipView layer]; // setting these here because I've had bad experiences with NSView changing some layer properties out from under me. - clipLayer.geometryFlipped = YES; + clipLayer.geometryFlipped = NO; // always make sure it's at the very bottom [layer insertSublayer:clipLayer atIndex:0]; From 6498cad60cdb7f22bd101af66615a398359d7d0b Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 09:23:08 -0500 Subject: [PATCH 09/39] =?UTF-8?q?Add=20the=20ability=20to=20change=20a=20U?= =?UTF-8?q?IActivityIndicatorView=E2=80=99s=20colour.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UIKit/Classes/UIActivityIndicatorView.h | 2 +- UIKit/Classes/UIActivityIndicatorView.m | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/UIKit/Classes/UIActivityIndicatorView.h b/UIKit/Classes/UIActivityIndicatorView.h index 71fe74b5..5f99de5e 100644 --- a/UIKit/Classes/UIActivityIndicatorView.h +++ b/UIKit/Classes/UIActivityIndicatorView.h @@ -49,5 +49,5 @@ typedef enum { @property BOOL hidesWhenStopped; @property UIActivityIndicatorViewStyle activityIndicatorViewStyle; - +@property (retain) UIColor *color; @end diff --git a/UIKit/Classes/UIActivityIndicatorView.m b/UIKit/Classes/UIActivityIndicatorView.m index af715172..f30c07de 100644 --- a/UIKit/Classes/UIActivityIndicatorView.m +++ b/UIKit/Classes/UIActivityIndicatorView.m @@ -45,15 +45,13 @@ static CGSize UIActivityIndicatorViewStyleSize(UIActivityIndicatorViewStyle styl } } -static UIImage *UIActivityIndicatorViewFrameImage(UIActivityIndicatorViewStyle style, NSInteger frame, NSInteger numberOfFrames, CGFloat scale) +static UIImage *UIActivityIndicatorViewFrameImage(UIActivityIndicatorViewStyle style, NSInteger frame, NSInteger numberOfFrames, CGFloat scale, UIColor *toothColor) { const CGSize frameSize = UIActivityIndicatorViewStyleSize(style); const CGFloat radius = frameSize.width / 2.f; const CGFloat TWOPI = M_PI * 2.f; const CGFloat numberOfTeeth = 12; const CGFloat toothWidth = (style == UIActivityIndicatorViewStyleWhiteLarge)? 3.5 : 2; - - UIColor *toothColor = (style == UIActivityIndicatorViewStyleGray)? [UIColor grayColor] : [UIColor whiteColor]; UIGraphicsBeginImageContextWithOptions(frameSize, NO, scale); CGContextRef c = UIGraphicsGetCurrentContext(); @@ -176,7 +174,7 @@ - (void)_startAnimation NSMutableArray *images = [[NSMutableArray alloc] initWithCapacity:numberOfFrames]; for (NSInteger frameNumber=0; frameNumber Date: Tue, 12 Nov 2013 09:24:26 -0500 Subject: [PATCH 10/39] Use [self class] instead of isa. --- UIKit/Classes/UIAction.m | 2 +- UIKit/Classes/UIFont.m | 2 +- UIKit/Classes/UILongPressGestureRecognizer.m | 2 +- UIKit/Classes/UIMenuController.m | 2 +- UIKit/Classes/UINavigationBar.m | 6 +++--- UIKit/Classes/UINavigationItem.m | 4 ++-- UIKit/Classes/UIPopoverView.m | 6 +++--- UIKit/Classes/UIResponder.m | 2 +- UIKit/Classes/UIView.m | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/UIKit/Classes/UIAction.m b/UIKit/Classes/UIAction.m index 5378ff5d..0afcf14a 100644 --- a/UIKit/Classes/UIAction.m +++ b/UIKit/Classes/UIAction.m @@ -36,7 +36,7 @@ - (BOOL)isEqual:(id)object { if (object == self) { return YES; - } else if ([object isKindOfClass:[isa class]]) { + } else if ([object isKindOfClass:[self class]]) { return ([object target] == self.target && [object action] == self.action); } else { return NO; diff --git a/UIKit/Classes/UIFont.m b/UIKit/Classes/UIFont.m index dcbab16e..46459c95 100644 --- a/UIKit/Classes/UIFont.m +++ b/UIKit/Classes/UIFont.m @@ -191,7 +191,7 @@ - (UIFont *)fontWithSize:(CGFloat)fontSize { CTFontRef newFont = CTFontCreateCopyWithAttributes(_font, fontSize, NULL, NULL); if (newFont) { - UIFont *theFont = [isa _fontWithCTFont:newFont]; + UIFont *theFont = [[self class] _fontWithCTFont:newFont]; CFRelease(newFont); return theFont; } else { diff --git a/UIKit/Classes/UILongPressGestureRecognizer.m b/UIKit/Classes/UILongPressGestureRecognizer.m index 6eabf1a4..9723ea54 100644 --- a/UIKit/Classes/UILongPressGestureRecognizer.m +++ b/UIKit/Classes/UILongPressGestureRecognizer.m @@ -83,7 +83,7 @@ - (void)_cancelWaiting { if (_waiting) { _waiting = NO; - [isa cancelPreviousPerformRequestsWithTarget:self selector:@selector(_beginGesture) object:nil]; + [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(_beginGesture) object:nil]; } } diff --git a/UIKit/Classes/UIMenuController.m b/UIKit/Classes/UIMenuController.m index d5c0637c..9a74feda 100644 --- a/UIKit/Classes/UIMenuController.m +++ b/UIKit/Classes/UIMenuController.m @@ -194,7 +194,7 @@ - (void)update { UIApplication *app = [UIApplication sharedApplication]; UIResponder *firstResponder = [app.keyWindow _firstResponder]; - NSArray *allItems = [[isa _defaultMenuItems] arrayByAddingObjectsFromArray:_menuItems]; + NSArray *allItems = [[[self class] _defaultMenuItems] arrayByAddingObjectsFromArray:_menuItems]; [_enabledMenuItems removeAllObjects]; diff --git a/UIKit/Classes/UINavigationBar.m b/UIKit/Classes/UINavigationBar.m index 226deeb4..8b5c98e0 100644 --- a/UIKit/Classes/UINavigationBar.m +++ b/UIKit/Classes/UINavigationBar.m @@ -201,9 +201,9 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: CGRect rightFrame = CGRectZero; if (backItem) { - _leftView = [isa _backButtonWithBarButtonItem:backItem.backBarButtonItem]; + _leftView = [[self class] _backButtonWithBarButtonItem:backItem.backBarButtonItem]; } else { - _leftView = [isa _viewWithBarButtonItem:topItem.leftBarButtonItem]; + _leftView = [[self class] _viewWithBarButtonItem:topItem.leftBarButtonItem]; } if (_leftView) { @@ -213,7 +213,7 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: [self addSubview:_leftView]; } - _rightView = [isa _viewWithBarButtonItem:topItem.rightBarButtonItem]; + _rightView = [[self class] _viewWithBarButtonItem:topItem.rightBarButtonItem]; if (_rightView) { _rightView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; diff --git a/UIKit/Classes/UINavigationItem.m b/UIKit/Classes/UINavigationItem.m index 13157ea2..8c799661 100644 --- a/UIKit/Classes/UINavigationItem.m +++ b/UIKit/Classes/UINavigationItem.m @@ -90,13 +90,13 @@ - (void)_setNavigationBar:(UINavigationBar *)navigationBar if (_navigationBar != nil && navigationBar == nil) { // remove observation - for (NSString * keyPath in [isa _keyPathsTriggeringUIUpdates]) { + for (NSString * keyPath in [[self class] _keyPathsTriggeringUIUpdates]) { [self removeObserver:self forKeyPath:keyPath]; } } else if (navigationBar != nil) { // observe property changes to notify UI element - for (NSString * keyPath in [isa _keyPathsTriggeringUIUpdates]) { + for (NSString * keyPath in [[self class] _keyPathsTriggeringUIUpdates]) { [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:UINavigationItemContext]; } } diff --git a/UIKit/Classes/UIPopoverView.m b/UIKit/Classes/UIPopoverView.m index c10444a7..c425acec 100644 --- a/UIKit/Classes/UIPopoverView.m +++ b/UIKit/Classes/UIPopoverView.m @@ -164,8 +164,8 @@ - (void)layoutSubviews [super layoutSubviews]; const CGRect bounds = self.bounds; - _backgroundView.frame = [isa backgroundRectForBounds:bounds]; - _contentContainerView.frame = [isa contentRectForBounds:bounds withNavigationBar:NO]; + _backgroundView.frame = [[self class] backgroundRectForBounds:bounds]; + _contentContainerView.frame = [[self class] contentRectForBounds:bounds withNavigationBar:NO]; _contentView.frame = _contentContainerView.bounds; } @@ -312,7 +312,7 @@ - (void)setContentView:(UIView *)aView - (void)setContentSize:(CGSize)aSize animated:(BOOL)animated { CGRect frame = self.frame; - frame.size = [isa frameSizeForContentSize:aSize withNavigationBar:NO]; + frame.size = [[self class] frameSizeForContentSize:aSize withNavigationBar:NO]; [UIView animateWithDuration:animated? 0.2 : 0 animations:^(void) { diff --git a/UIKit/Classes/UIResponder.m b/UIKit/Classes/UIResponder.m index 55ece95e..4e97c18e 100644 --- a/UIKit/Classes/UIResponder.m +++ b/UIKit/Classes/UIResponder.m @@ -114,7 +114,7 @@ - (BOOL)resignFirstResponder - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { - if ([isa instancesRespondToSelector:action]) { + if ([[self class] instancesRespondToSelector:action]) { return YES; } else { return [[self nextResponder] canPerformAction:action withSender:sender]; diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index 1587db25..6bc1e4f4 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -81,7 +81,7 @@ - (id)init - (id)initWithFrame:(CGRect)theFrame { if ((self=[super init])) { - _implementsDrawRect = [isa _instanceImplementsDrawRect]; + _implementsDrawRect = [[self class] _instanceImplementsDrawRect]; _clearsContextBeforeDrawing = YES; _autoresizesSubviews = YES; _userInteractionEnabled = YES; @@ -90,7 +90,7 @@ - (id)initWithFrame:(CGRect)theFrame _frame = CGRectZero; - _layer = [[[isa layerClass] alloc] init]; + _layer = [[[[self class] layerClass] alloc] init]; _layer.delegate = self; _layer.layoutManager = [UIViewLayoutManager layoutManager]; From ef2dbc917136b1bec7690f3fae010586fa0ee52a Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 09:26:05 -0500 Subject: [PATCH 11/39] =?UTF-8?q?Stub=20in=20several=20features=20that=20d?= =?UTF-8?q?on=E2=80=99t=20make=20sense=20on=20OS=20X.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UIKit/Classes/UIApplication.h | 17 ++++++++++++++++- UIKit/Classes/UIApplication.m | 5 +++++ UIKit/Classes/UIDevice.h | 10 ++++++++++ UIKit/Classes/UIDevice.m | 10 ++++++++++ UIKit/Classes/UIScreen.h | 9 +++++++++ UIKit/Classes/UIScreen.m | 6 ++++++ UIKit/Classes/UIViewController.h | 2 ++ UIKit/Classes/UIViewController.m | 10 ++++++++++ UIKit/Classes/UIWebView.h | 5 +++++ 9 files changed, 73 insertions(+), 1 deletion(-) diff --git a/UIKit/Classes/UIApplication.h b/UIKit/Classes/UIApplication.h index d72a1f25..c3bf9377 100644 --- a/UIKit/Classes/UIApplication.h +++ b/UIKit/Classes/UIApplication.h @@ -64,6 +64,21 @@ typedef enum { UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft } UIInterfaceOrientation; +typedef enum : NSUInteger { + UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait), + UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft), + UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight), + UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown), + UIInterfaceOrientationMaskLandscape = + (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), + UIInterfaceOrientationMaskAll = + (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | + UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown), + UIInterfaceOrientationMaskAllButUpsideDown = + (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | + UIInterfaceOrientationMaskLandscapeRight), +} UIInterfaceOrientationMask; + #define UIInterfaceOrientationIsPortrait(orientation) \ ((orientation) == UIInterfaceOrientationPortrait || \ (orientation) == UIInterfaceOrientationPortraitUpsideDown) @@ -153,7 +168,7 @@ extern const NSTimeInterval UIMinimumKeepAliveTimeout; @property (nonatomic, readonly) UIWindow *keyWindow; @property (nonatomic, readonly) NSArray *windows; -@property (nonatomic, getter=isStatusBarHidden, readonly) BOOL statusBarHidden; +@property (nonatomic, getter=isStatusBarHidden) BOOL statusBarHidden; @property (nonatomic, readonly) CGRect statusBarFrame; @property (nonatomic, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; // does nothing, always returns NO @property (nonatomic) UIInterfaceOrientation statusBarOrientation; diff --git a/UIKit/Classes/UIApplication.m b/UIKit/Classes/UIApplication.m index b9ac380d..1ead4938 100644 --- a/UIKit/Classes/UIApplication.m +++ b/UIKit/Classes/UIApplication.m @@ -183,6 +183,11 @@ - (BOOL)isStatusBarHidden return YES; } +- (void)setStatusBarHidden:(BOOL)statusBarHidden +{ + // do nothing +} + - (CGRect)statusBarFrame { return CGRectZero; diff --git a/UIKit/Classes/UIDevice.h b/UIKit/Classes/UIDevice.h index c2ce9ea3..b65d9388 100644 --- a/UIKit/Classes/UIDevice.h +++ b/UIKit/Classes/UIDevice.h @@ -47,6 +47,13 @@ typedef enum { UIUserInterfaceIdiomDesktop, } UIUserInterfaceIdiom; +typedef enum { + UIDeviceBatteryStateUnknown, + UIDeviceBatteryStateUnplugged, + UIDeviceBatteryStateCharging, + UIDeviceBatteryStateFull, +} UIDeviceBatteryState; + #define UI_USER_INTERFACE_IDIOM() \ ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? \ [[UIDevice currentDevice] userInterfaceIdiom] : \ @@ -68,11 +75,14 @@ typedef enum { @property (nonatomic, readonly, retain) NSString *name; @property (nonatomic, readonly) UIUserInterfaceIdiom userInterfaceIdiom; // always returns UIUserInterfaceIdiomDesktop @property (nonatomic, readonly) UIDeviceOrientation orientation; // always returns UIDeviceOrientationPortrait +@property (nonatomic, readonly) UIDeviceBatteryState batteryState; // always returns UIDeviceBatteryStateUnknown +@property (nonatomic, readonly) float batteryLevel; // always returns -1.0 (unknown) @property (nonatomic, readonly,getter=isMultitaskingSupported) BOOL multitaskingSupported; // always returns YES @property (nonatomic, readonly, retain) NSString *systemName; @property (nonatomic, readonly, retain) NSString *systemVersion; @property (nonatomic, readonly, retain) NSString *model; @property (nonatomic, readonly, getter=isGeneratingDeviceOrientationNotifications) BOOL generatesDeviceOrientationNotifications; // aways returns NO +@property (nonatomic, assign) BOOL batteryMonitoringEnabled; - (void)beginGeneratingDeviceOrientationNotifications; // no effect - (void)endGeneratingDeviceOrientationNotifications; // no effect diff --git a/UIKit/Classes/UIDevice.m b/UIKit/Classes/UIDevice.m index a5622709..7ec77450 100644 --- a/UIKit/Classes/UIDevice.m +++ b/UIKit/Classes/UIDevice.m @@ -64,6 +64,16 @@ - (UIDeviceOrientation)orientation return UIDeviceOrientationPortrait; } +- (UIDeviceBatteryState)batteryState +{ + return UIDeviceBatteryStateUnknown; +} + +- (float)batteryLevel +{ + return -1.f; +} + - (BOOL)isMultitaskingSupported { return YES; diff --git a/UIKit/Classes/UIScreen.h b/UIKit/Classes/UIScreen.h index 78a8cd79..b148211d 100644 --- a/UIKit/Classes/UIScreen.h +++ b/UIKit/Classes/UIScreen.h @@ -34,6 +34,12 @@ extern NSString *const UIScreenDidConnectNotification; extern NSString *const UIScreenDidDisconnectNotification; extern NSString *const UIScreenModeDidChangeNotification; +typedef enum { + UIScreenOverscanCompensationScale, + UIScreenOverscanCompensationInsetBounds, + UIScreenOverscanCompensationInsetApplicationFrame, +} UIScreenOverscanCompensation; + @class UIImageView, CALayer, UIKitView, UIScreenMode, UIPopoverController; @interface UIScreen : NSObject { @@ -53,5 +59,8 @@ extern NSString *const UIScreenModeDidChangeNotification; @property (nonatomic, readonly, copy) NSArray *availableModes; // only ever returns the currentMode @property (nonatomic, retain) UIScreenMode *currentMode; // ignores any attempt to set this @property (nonatomic, readonly) CGFloat scale; +@property (nonatomic, assign) UIScreenOverscanCompensation overscanCompensation; // has no effect +@property (nonatomic, assign) BOOL mirroredScreen; // always returns NO +@property (nonatomic) CGFloat brightness; // has no effect; defaults to 0.0 @end diff --git a/UIKit/Classes/UIScreen.m b/UIKit/Classes/UIScreen.m index 0d1bae52..59f4e989 100644 --- a/UIKit/Classes/UIScreen.m +++ b/UIKit/Classes/UIScreen.m @@ -49,6 +49,7 @@ @implementation UIScreen @synthesize currentMode=_currentMode; +@synthesize overscanCompensation; + (void)initialize { @@ -242,4 +243,9 @@ - (NSString *)description return [NSString stringWithFormat:@"<%@: %p; bounds = %@; mode = %@>", [self className], self, NSStringFromCGRect(self.bounds), self.currentMode]; } +- (BOOL)mirroredScreen +{ + return NO; +} + @end diff --git a/UIKit/Classes/UIViewController.h b/UIKit/Classes/UIViewController.h index 87796790..4a098b5f 100644 --- a/UIKit/Classes/UIViewController.h +++ b/UIKit/Classes/UIViewController.h @@ -105,6 +105,8 @@ typedef enum { @property (nonatomic, readonly, retain) NSBundle *nibBundle; // always returns nil @property (nonatomic, retain) UIView *view; @property (nonatomic, assign) BOOL wantsFullScreenLayout; // doesn't do anything right now +@property (nonatomic, assign) BOOL shouldAutorotate; // always returns NO +@property (nonatomic, assign) NSUInteger supportedInterfaceOrientations; // always returns UIInterfaceOrientationLandscapeLeft @property (nonatomic, copy) NSString *title; @property (nonatomic, readonly) UIInterfaceOrientation interfaceOrientation; // always returns UIInterfaceOrientationLandscapeLeft @property (nonatomic, readonly, retain) UINavigationItem *navigationItem; diff --git a/UIKit/Classes/UIViewController.m b/UIKit/Classes/UIViewController.m index 6d0ec441..9e49b595 100644 --- a/UIKit/Classes/UIViewController.m +++ b/UIKit/Classes/UIViewController.m @@ -298,4 +298,14 @@ - (NSString *)description return [NSString stringWithFormat:@"<%@: %p; title = %@; view = %@>", [self className], self, self.title, self.view]; } +- (BOOL)shouldAutorotate +{ + return NO; +} + +- (NSUInteger)supportedInterfaceOrientations +{ + return UIInterfaceOrientationLandscapeLeft; +} + @end diff --git a/UIKit/Classes/UIWebView.h b/UIKit/Classes/UIWebView.h index 768934f7..35e15f20 100644 --- a/UIKit/Classes/UIWebView.h +++ b/UIKit/Classes/UIWebView.h @@ -82,4 +82,9 @@ typedef NSUInteger UIWebViewNavigationType; @property (nonatomic, readonly, retain) NSURLRequest *request; @property (nonatomic) UIDataDetectorTypes dataDetectorTypes; +@property (nonatomic, assign) BOOL allowsInlineMediaPlayback; +@property (nonatomic, assign) BOOL mediaPlaybackRequiresUserAction; +@property (nonatomic, assign) BOOL mediaPlaybackAllowsAirPlay; +@property (nonatomic, assign) BOOL keyboardDisplayRequiresUserAction; + @end From 91db1ac1a0ff6519e48eb7e8a56bccff1620d5f6 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 09:26:43 -0500 Subject: [PATCH 12/39] Make [UIImage imageNamed:] support TIFF files. --- UIKit/Classes/UIImage.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIKit/Classes/UIImage.m b/UIKit/Classes/UIImage.m index 7948a19b..cda552d4 100644 --- a/UIKit/Classes/UIImage.m +++ b/UIKit/Classes/UIImage.m @@ -59,7 +59,7 @@ + (id)imageNamed:(NSString *)name if (!img) { // as per the iOS docs, if it fails to find a match with the bare name, it re-tries by appending a png file extension - img = [self _imageNamed:name] ?: [self _imageNamed:[name stringByAppendingPathExtension:@"png"]]; + img = [self _imageNamed:name] ?: [self _imageNamed:[name stringByAppendingPathExtension:@"png"]] ?: [self _imageNamed:[name stringByAppendingPathExtension:@"tiff"]]; [self _cacheImage:img forName:name]; } From 4cd5639a690d489cd285e028f12f45d9a4462ef7 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 11:28:11 -0500 Subject: [PATCH 13/39] Implement drawing of UIProgressView controls. --- UIKit/Classes/UIProgressView.h | 2 ++ UIKit/Classes/UIProgressView.m | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/UIKit/Classes/UIProgressView.h b/UIKit/Classes/UIProgressView.h index 15f359b4..50afe7ef 100644 --- a/UIKit/Classes/UIProgressView.h +++ b/UIKit/Classes/UIProgressView.h @@ -43,5 +43,7 @@ typedef enum { @property (nonatomic) UIProgressViewStyle progressViewStyle; @property (nonatomic) float progress; +@property (nonatomic, strong) UIColor *progressTintColor; +@property (nonatomic, strong) UIColor *trackTintColor; @end diff --git a/UIKit/Classes/UIProgressView.m b/UIKit/Classes/UIProgressView.m index 514f8b74..bf593fbf 100644 --- a/UIKit/Classes/UIProgressView.m +++ b/UIKit/Classes/UIProgressView.m @@ -28,6 +28,8 @@ */ #import "UIProgressView.h" +#import "UIGraphics.h" +#import "UIColor.h" @implementation UIProgressView @synthesize progressViewStyle=_progressViewStyle, progress=_progress; @@ -56,4 +58,22 @@ - (void)setProgress:(float)p } } +- (void)drawRect:(CGRect)rect { + int totalWidth = self.frame.size.width; + int filledWidth = totalWidth * self->_progress; + + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSaveGState(context); + + // draw the background part of the bar + CGContextSetFillColorWithColor(context, self.trackTintColor.CGColor); + CGContextFillRect(context, CGRectMake(0, 0, totalWidth, self.frame.size.height)); + + // draw the filled part of the bar + CGContextSetFillColorWithColor(context, self.progressTintColor.CGColor); + CGContextFillRect(context, CGRectMake(0, 0, filledWidth, self.frame.size.height)); + + CGContextRestoreGState(context); +} + @end From 07e8fc5647b75ee030c870e86f8c8d97a104c116 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 14:32:43 -0500 Subject: [PATCH 14/39] UITextLayer: Fix the alignment of the text to the clipping rect. --- UIKit/Classes/UITextLayer.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIKit/Classes/UITextLayer.m b/UIKit/Classes/UITextLayer.m index 638e48ab..4d246a04 100644 --- a/UIKit/Classes/UITextLayer.m +++ b/UIKit/Classes/UITextLayer.m @@ -154,7 +154,7 @@ - (void)updateNSViews [clipView setFrame:desiredFrame]; [self updateScrollViewContentSize]; - clipView.layer.geometryFlipped = YES; + clipView.layer.geometryFlipped = NO; } else { [self removeNSView]; } From 220121a799fe936e9771ea7b7d84dc03870a1765 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 14:34:04 -0500 Subject: [PATCH 15/39] Fix a warning: Xcode thinks [anId window] returns an (NSWindow *). --- UIKit/Classes/UITextLayer.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIKit/Classes/UITextLayer.m b/UIKit/Classes/UITextLayer.m index 4d246a04..577013da 100644 --- a/UIKit/Classes/UITextLayer.m +++ b/UIKit/Classes/UITextLayer.m @@ -147,7 +147,7 @@ - (void)updateNSViews [self addNSView]; } - UIWindow *window = [containerView window]; + UIWindow *window = [(UIView *)containerView window]; const CGRect windowRect = [window convertRect:self.frame fromView:containerView]; const CGRect screenRect = [window convertRect:windowRect toWindow:nil]; NSRect desiredFrame = NSRectFromCGRect(screenRect); From 90ac5b49db45282eb6c122a4dc607713d2e175c3 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 14:36:28 -0500 Subject: [PATCH 16/39] =?UTF-8?q?Make=20UITextField=20update=20its=20text?= =?UTF-8?q?=20layer=E2=80=99s=20visibility.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caveat: The text layer (independent of its superview) should probably still be “not hidden” even when the text field is hidden. However, without adding additional plumbing to make UITextLayer update its NSViews, this is a reasonable solution to make UITextLayer create an NSView when unhidden. --- UIKit/Classes/UITextField.m | 5 +++++ UIKit/Classes/UITextLayer.m | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/UIKit/Classes/UITextField.m b/UIKit/Classes/UITextField.m index 27f24fed..aae8694e 100644 --- a/UIKit/Classes/UITextField.m +++ b/UIKit/Classes/UITextField.m @@ -194,6 +194,11 @@ - (void)setFrame:(CGRect)frame } } +- (void)setHidden:(BOOL)hidden +{ + [super setHidden:hidden]; + [_textLayer setHidden:hidden]; +} - (CGRect)borderRectForBounds:(CGRect)bounds { diff --git a/UIKit/Classes/UITextLayer.m b/UIKit/Classes/UITextLayer.m index 577013da..bf2a42d1 100644 --- a/UIKit/Classes/UITextLayer.m +++ b/UIKit/Classes/UITextLayer.m @@ -413,9 +413,7 @@ - (BOOL)textViewResignFirstResponder:(UICustomNSTextView *)aTextView - (BOOL)becomeFirstResponder { - if ([self shouldBeVisible] && ![clipView superview]) { - [self addNSView]; - } + [self updateNSViews]; changingResponderStatus = YES; const BOOL result = [[textView window] makeFirstResponder:textView]; From bd8b3d8808a6190dc2857186d493bde9800822fa Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 12 Nov 2013 15:33:56 -0500 Subject: [PATCH 17/39] =?UTF-8?q?Hack:=20Always=20call=20the=20subview?= =?UTF-8?q?=E2=80=99s=20viewWillAppear,=20viewWillDisappear,=20etc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This disables the [UIView _needsDidAppearOrDisappear] by always making it equal YES. To be honest, I don’t understand what its purpose is, but this appears to cause no side effects. --- UIKit/Classes/UIView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index 6bc1e4f4..636fc41d 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -230,7 +230,7 @@ - (void)addSubview:(UIView *)subview UIWindow *oldWindow = subview.window; UIWindow *newWindow = self.window; - subview->_needsDidAppearOrDisappear = [self _subviewControllersNeedAppearAndDisappear]; + subview->_needsDidAppearOrDisappear = YES;//[self _subviewControllersNeedAppearAndDisappear]; if ([subview _viewController] && subview->_needsDidAppearOrDisappear) { [[subview _viewController] viewWillAppear:NO]; From f022554351050e62788082b7a40c18c8ea2c27e0 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 14 Nov 2013 13:55:15 -0500 Subject: [PATCH 18/39] Make -[UIScreen mirrorredScreen] return a UIScreen * instead of BOOL. --- UIKit/Classes/UIScreen.h | 2 +- UIKit/Classes/UIScreen.m | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/UIKit/Classes/UIScreen.h b/UIKit/Classes/UIScreen.h index b148211d..75339d2e 100644 --- a/UIKit/Classes/UIScreen.h +++ b/UIKit/Classes/UIScreen.h @@ -60,7 +60,7 @@ typedef enum { @property (nonatomic, retain) UIScreenMode *currentMode; // ignores any attempt to set this @property (nonatomic, readonly) CGFloat scale; @property (nonatomic, assign) UIScreenOverscanCompensation overscanCompensation; // has no effect -@property (nonatomic, assign) BOOL mirroredScreen; // always returns NO +@property (nonatomic, retain) UIScreen *mirroredScreen; // always returns nil @property (nonatomic) CGFloat brightness; // has no effect; defaults to 0.0 @end diff --git a/UIKit/Classes/UIScreen.m b/UIKit/Classes/UIScreen.m index 59f4e989..d2ff96f4 100644 --- a/UIKit/Classes/UIScreen.m +++ b/UIKit/Classes/UIScreen.m @@ -243,9 +243,9 @@ - (NSString *)description return [NSString stringWithFormat:@"<%@: %p; bounds = %@; mode = %@>", [self className], self, NSStringFromCGRect(self.bounds), self.currentMode]; } -- (BOOL)mirroredScreen +- (UIScreen *)mirroredScreen { - return NO; + return nil; } @end From 8ddbcfe1da54be0fee7f39a3897a1bb5cdfe1c32 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 14 Nov 2013 13:56:30 -0500 Subject: [PATCH 19/39] =?UTF-8?q?Add=20UIViewController=20{present/dismiss?= =?UTF-8?q?}ViewController=E2=80=A6=20methods.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UIKit/Classes/UIViewController.h | 3 +++ UIKit/Classes/UIViewController.m | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/UIKit/Classes/UIViewController.h b/UIKit/Classes/UIViewController.h index 4a098b5f..92cfcaa2 100644 --- a/UIKit/Classes/UIViewController.h +++ b/UIKit/Classes/UIViewController.h @@ -89,6 +89,9 @@ typedef enum { - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated; // works, but not exactly correctly. - (void)dismissModalViewControllerAnimated:(BOOL)animated; // see comments in dismissModalViewController +- (void)presentViewController:(UIViewController *)modalViewController animated:(BOOL)animated completion:(void(^)(void))completion; +- (void)dismissViewControllerAnimated:(BOOL)animated completion:(void(^)(void))completion; + - (void)didReceiveMemoryWarning; // doesn't do anything and is never called... - (void)setToolbarItems:(NSArray *)toolbarItems animated:(BOOL)animated; diff --git a/UIKit/Classes/UIViewController.m b/UIKit/Classes/UIViewController.m index 9e49b595..c73e286d 100644 --- a/UIKit/Classes/UIViewController.m +++ b/UIKit/Classes/UIViewController.m @@ -255,6 +255,28 @@ - (void)dismissModalViewControllerAnimated:(BOOL)animated } } +- (void)presentViewController:(UIViewController *)modalViewController animated:(BOOL)animated completion:(void(^)(void))completion +{ + // this isn't exactly right either, but close enough + [self presentModalViewController:modalViewController animated:animated]; + + if (completion != NULL) { + completion(); + } +} + +- (void)dismissViewControllerAnimated:(BOOL)animated completion:(void(^)(void))completion +{ + // this isn't exactly right either, but close enough + [self dismissModalViewControllerAnimated:animated]; + + if (completion != NULL) { + completion(); + } +} + + + - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait); From bb7754ecb0e8c498186aa881f3add88402205bac Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Fri, 15 Nov 2013 12:53:51 -0500 Subject: [PATCH 20/39] Make NSIndexPath+UITableView use signed integers. --- UIKit/Classes/NSIndexPath+UITableView.h | 6 +++--- UIKit/Classes/NSIndexPath+UITableView.m | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/UIKit/Classes/NSIndexPath+UITableView.h b/UIKit/Classes/NSIndexPath+UITableView.h index b39e618d..7ed0a4de 100644 --- a/UIKit/Classes/NSIndexPath+UITableView.h +++ b/UIKit/Classes/NSIndexPath+UITableView.h @@ -30,7 +30,7 @@ #import @interface NSIndexPath (UITableView) -+ (NSIndexPath *)indexPathForRow:(NSUInteger)row inSection:(NSUInteger)section; -@property (readonly) NSUInteger row; -@property (readonly) NSUInteger section; ++ (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section; +@property (readonly) NSInteger row; +@property (readonly) NSInteger section; @end diff --git a/UIKit/Classes/NSIndexPath+UITableView.m b/UIKit/Classes/NSIndexPath+UITableView.m index b3cda59a..687d8fe2 100644 --- a/UIKit/Classes/NSIndexPath+UITableView.m +++ b/UIKit/Classes/NSIndexPath+UITableView.m @@ -31,18 +31,18 @@ @implementation NSIndexPath (UITableView) -+ (NSIndexPath *)indexPathForRow:(NSUInteger)row inSection:(NSUInteger)section ++ (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section { - NSUInteger path[2] = {section, row}; + NSInteger path[2] = {section, row}; return [self indexPathWithIndexes:path length:2]; } -- (NSUInteger)row +- (NSInteger)row { return [self indexAtPosition:1]; } --(NSUInteger)section +-(NSInteger)section { return [self indexAtPosition:0]; } From 36798e35f92c6102b7ee014e0398f6f376d58a65 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 21 Nov 2013 10:55:29 -0500 Subject: [PATCH 21/39] Make UITextField display placeholders. --- UIKit/Classes/UITextField.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/UIKit/Classes/UITextField.m b/UIKit/Classes/UITextField.m index aae8694e..c19a64d5 100644 --- a/UIKit/Classes/UITextField.m +++ b/UIKit/Classes/UITextField.m @@ -292,6 +292,8 @@ - (CGRect)textRectForBounds:(CGRect)bounds - (void)drawPlaceholderInRect:(CGRect)rect { + [[UIColor colorWithWhite:0.7 alpha:1.0] set]; + [self->_placeholder drawInRect:rect withFont:self.font]; } - (void)drawTextInRect:(CGRect)rect @@ -302,6 +304,10 @@ - (void)drawRect:(CGRect)rect { UIImage *background = self.enabled? _background : _disabledBackground; [background drawInRect:self.bounds]; + + if ([self.text length] == 0) { + [self drawPlaceholderInRect:[self placeholderRectForBounds:self.bounds]]; + } } From 5e5388fc0c839f5b5c2a5032d4b01b593444f5ef Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 21 Nov 2013 13:42:22 -0500 Subject: [PATCH 22/39] Fix alignment of text and placeholders in text fields to match iOS. --- UIKit/Classes/UICustomNSTextView.m | 8 ++++++++ UIKit/Classes/UITextField.m | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/UIKit/Classes/UICustomNSTextView.m b/UIKit/Classes/UICustomNSTextView.m index cc3165ba..6523de5e 100644 --- a/UIKit/Classes/UICustomNSTextView.m +++ b/UIKit/Classes/UICustomNSTextView.m @@ -121,10 +121,18 @@ - (void)updateStyles [style setLineBreakMode:NSLineBreakByTruncatingTail]; } + // eliminate the built-in padding around the text field + [[self textContainer] setLineFragmentPadding:0]; + [self setDefaultParagraphStyle:style]; [style release]; } +// vertically centre the text +- (NSPoint)textContainerOrigin { + return NSMakePoint(0, (self.font.ascender + self.font.descender + self.font.xHeight)/2); +} + - (void)setSecureTextEntry:(BOOL)isSecure { secureTextEntry = isSecure; diff --git a/UIKit/Classes/UITextField.m b/UIKit/Classes/UITextField.m index c19a64d5..2fe1951a 100644 --- a/UIKit/Classes/UITextField.m +++ b/UIKit/Classes/UITextField.m @@ -292,8 +292,12 @@ - (CGRect)textRectForBounds:(CGRect)bounds - (void)drawPlaceholderInRect:(CGRect)rect { + // inset the rect by the offset required to vertically centre the text + CGFloat fontHeight = self.font.ascender + self.font.xHeight; + CGRect placeholderRect = CGRectInset(rect, 0, (rect.size.height - fontHeight) / 2); + [[UIColor colorWithWhite:0.7 alpha:1.0] set]; - [self->_placeholder drawInRect:rect withFont:self.font]; + [self->_placeholder drawInRect:placeholderRect withFont:self.font]; } - (void)drawTextInRect:(CGRect)rect From d9a47e7e0d81421c8fbb263d62da10fe6e192588 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Thu, 21 Nov 2013 15:45:20 -0500 Subject: [PATCH 23/39] Keep persistent UIWebView local storage database. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store the database in ~/Library/Application Support/{App name}/WebKit/LocalStorage so it’s sandboxed to the application and persistent across multiple runs. --- UIKit/Classes/UIWebView.m | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/UIKit/Classes/UIWebView.m b/UIKit/Classes/UIWebView.m index c825f8bf..2b6267e1 100644 --- a/UIKit/Classes/UIWebView.m +++ b/UIKit/Classes/UIWebView.m @@ -38,11 +38,22 @@ - (void) setDatabasesEnabled:(BOOL)databasesEnabled; - (void) setDeveloperExtrasEnabled:(BOOL)developerExtrasEnabled; - (void) setWebGLEnabled:(BOOL)webGLEnabled; - (void) setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled; + +- (NSString *)_localStorageDatabasePath; +- (void)_setLocalStorageDatabasePath:(NSString *)path; @end @implementation UIWebView @synthesize request=_request, delegate=_delegate, dataDetectorTypes=_dataDetectorTypes, scalesPageToFit=_scalesPageToFit; +- (NSString *)_localStorageDatabasePath +{ + NSString *appName = [[NSRunningApplication currentApplication] localizedName]; + NSURL *applicationSupport = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] firstObject]; + NSString *databasePath = [NSString stringWithFormat:@"%@/%@/WebKit/LocalStorage", [applicationSupport path], appName]; + return databasePath; +} + - (id)initWithFrame:(CGRect)frame { if ((self=[super initWithFrame:frame])) { @@ -58,6 +69,8 @@ - (id)initWithFrame:(CGRect)frame WebPreferences *preferences = [WebPreferences standardPreferences]; [preferences setOfflineWebApplicationCacheEnabled:YES]; [preferences setDeveloperExtrasEnabled:YES]; + [preferences _setLocalStorageDatabasePath:[self _localStorageDatabasePath]]; + [preferences setLocalStorageEnabled:YES]; [_webView setPreferences:preferences]; From cb12404a9536dfe03d91ba622cb7bd7b76f2f378 Mon Sep 17 00:00:00 2001 From: Rob Nielsen Date: Fri, 22 Nov 2013 14:30:16 -0500 Subject: [PATCH 24/39] Add UIAccessibilityIsGuidedAccessEnabled --- UIKit/Classes/UIAccessibility.h | 1 + UIKit/Classes/UIAccessibility.m | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/UIKit/Classes/UIAccessibility.h b/UIKit/Classes/UIAccessibility.h index a0aadcbf..7d62ceff 100644 --- a/UIKit/Classes/UIAccessibility.h +++ b/UIKit/Classes/UIAccessibility.h @@ -77,4 +77,5 @@ extern UIAccessibilityNotifications UIAccessibilityPageScrolledNotification; @end extern void UIAccessibilityPostNotification(UIAccessibilityNotifications notification, id argument); +extern BOOL UIAccessibilityIsGuidedAccessEnabled(void); extern BOOL UIAccessibilityIsVoiceOverRunning(void); diff --git a/UIKit/Classes/UIAccessibility.m b/UIKit/Classes/UIAccessibility.m index 4cff6f6f..8edb1676 100644 --- a/UIKit/Classes/UIAccessibility.m +++ b/UIKit/Classes/UIAccessibility.m @@ -163,6 +163,12 @@ void UIAccessibilityPostNotification(UIAccessibilityNotifications notification, { } + +BOOL UIAccessibilityIsGuidedAccessEnabled() +{ + return NO; +} + BOOL UIAccessibilityIsVoiceOverRunning() { return NO; From 8c6809746430b011fa0b359ba76fad6864a37044 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Wed, 19 Mar 2014 17:28:04 -0400 Subject: [PATCH 25/39] Make UIDevice report proper battery/power info --- UIKit/Classes/UIDevice.m | 52 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/UIKit/Classes/UIDevice.m b/UIKit/Classes/UIDevice.m index 7ec77450..5e9e7229 100644 --- a/UIKit/Classes/UIDevice.m +++ b/UIKit/Classes/UIDevice.m @@ -30,6 +30,7 @@ #import "UIDevice.h" #import #import +#import NSString *const UIDeviceOrientationDidChangeNotification = @"UIDeviceOrientationDidChangeNotification"; @@ -64,14 +65,61 @@ - (UIDeviceOrientation)orientation return UIDeviceOrientationPortrait; } + +- (NSDictionary *)primaryPowerSource +{ + CFTypeRef powerSourceInfo = IOPSCopyPowerSourcesInfo(); + CFArrayRef powerSources = IOPSCopyPowerSourcesList(powerSourceInfo); + + if (CFArrayGetCount(powerSources) == 0) return nil; + + CFDictionaryRef primarySourceRef = IOPSGetPowerSourceDescription(powerSourceInfo, CFArrayGetValueAtIndex(powerSources, 0)); + NSDictionary *primarySource = [NSDictionary dictionaryWithDictionary:[(__bridge NSDictionary *) primarySourceRef copy]]; + + CFRelease(primarySourceRef); + CFRelease(powerSourceInfo); + CFRelease(powerSources); + + return primarySource; +} + - (UIDeviceBatteryState)batteryState { - return UIDeviceBatteryStateUnknown; + UIDeviceBatteryState state = UIDeviceBatteryStateUnknown; + + NSDictionary *powerSource = [self primaryPowerSource]; + id powerSourceState = [powerSource objectForKey:(__bridge NSString *)CFSTR(kIOPSPowerSourceStateKey)]; + + if ([powerSourceState isEqualToString:(__bridge NSString *)CFSTR(kIOPSACPowerValue)]) { + id currentObj = [powerSource objectForKey:(__bridge NSString *)CFSTR(kIOPSCurrentCapacityKey)]; + id capacityObj = [powerSource objectForKey:(__bridge NSString *)CFSTR(kIOPSMaxCapacityKey)]; + + if ([currentObj isEqualToNumber:capacityObj]) { + state = UIDeviceBatteryStateFull; + } else { + state = UIDeviceBatteryStateCharging; + } + } else if ([powerSourceState isEqualToString:(__bridge NSString *)CFSTR(kIOPSBatteryPowerValue)]) { + state = UIDeviceBatteryStateUnplugged; + } + + return state; } - (float)batteryLevel { - return -1.f; + float batteryLevel = 1.f; + + NSDictionary *powerSource = [self primaryPowerSource]; + + if (powerSource != nil) { + id currentObj = [powerSource objectForKey:(__bridge NSString *)CFSTR(kIOPSCurrentCapacityKey)]; + id capacityObj = [powerSource objectForKey:(__bridge NSString *)CFSTR(kIOPSMaxCapacityKey)]; + + batteryLevel = [currentObj floatValue] / [capacityObj floatValue]; + } + + return batteryLevel; } - (BOOL)isMultitaskingSupported From 42ef8fba726d57a3432a8250b28442952238be7a Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Mon, 24 Mar 2014 16:13:06 -0400 Subject: [PATCH 26/39] Add support for tab navigation mimicking the iOS Simulator behaviour. I'm basing this on the behaviour described in this SO post: http://stackoverflow.com/questions/5317417/how-do-you-set-the-tab-order-in-ios --- UIKit/Classes/UIApplication.m | 54 +++++++++++++++++++++++++++++ UIKit/Classes/UIKey.h | 1 + UIKit/Classes/UIKey.m | 1 + UIKit/Classes/UITextField.m | 2 ++ UIKit/Classes/UITextLayer+Private.h | 35 +++++++++++++++++++ UIKit/Classes/UITextLayer.m | 3 ++ UITextField+Private.h | 35 +++++++++++++++++++ 7 files changed, 131 insertions(+) create mode 100644 UIKit/Classes/UITextLayer+Private.h create mode 100644 UITextField+Private.h diff --git a/UIKit/Classes/UIApplication.m b/UIKit/Classes/UIApplication.m index 1ead4938..73f6e529 100644 --- a/UIKit/Classes/UIApplication.m +++ b/UIKit/Classes/UIApplication.m @@ -40,6 +40,11 @@ #import "UIKey+UIPrivate.h" #import "UIBackgroundTask.h" #import +#import "UITextLayer.h" +#import "UITextLayer+Private.h" +#import "UITextField.h" +#import "UITextField+Private.h" + NSString *const UIApplicationWillChangeStatusBarOrientationNotification = @"UIApplicationWillChangeStatusBarOrientationNotification"; NSString *const UIApplicationDidChangeStatusBarOrientationNotification = @"UIApplicationDidChangeStatusBarOrientationNotification"; @@ -611,6 +616,55 @@ - (BOOL)_sendGlobalKeyboardNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *) return [self _sendActionToFirstResponder:@selector(commit:) withSender:key fromScreen:theScreen]; } } + + if (key.type == UIKeyTypeTab) { + UIResponder *firstResponder = [self _firstResponderForScreen:theScreen]; + + // the open list for an interative depth-first traversal + NSMutableArray *open = [NSMutableArray array]; + [open addObjectsFromArray:self.keyWindow.subviews]; + + NSMutableArray *allTextFields = [NSMutableArray array]; + + while(open.count > 0) + { + UIView *view = [open objectAtIndex:0]; + [open removeObjectAtIndex:0]; + [open addObjectsFromArray:view.subviews]; + + if ([view isKindOfClass:[UITextField class]]) { + if ([[(UITextField *)view textLayer] textShouldBeginEditing:nil]) { + [allTextFields addObject:view]; + } + } + } + + if ([allTextFields count] > 0) { + [allTextFields sortUsingComparator:^NSComparisonResult(id fieldOne, id fieldTwo) { + NSRect fieldOneBounds = [(UITextField *)fieldOne bounds]; + NSRect fieldTwoBounds = [(UITextField *)fieldTwo bounds]; + + NSComparator comparator = ^(NSNumber *obj1, NSNumber *obj2) { + if ([obj1 intValue] == [obj2 intValue]) return NSOrderedSame; + else if ([obj1 intValue] < [obj2 intValue]) return NSOrderedAscending; + else return NSOrderedDescending; + }; + + NSComparisonResult horizontalComparison = comparator(@(fieldOneBounds.origin.x), @(fieldTwoBounds.origin.x)); + NSComparisonResult verticalComparison = comparator(@(fieldOneBounds.origin.y), @(fieldTwoBounds.origin.y)); + + return horizontalComparison == NSOrderedSame ? verticalComparison : horizontalComparison; + }]; + + int currentIndex = [allTextFields containsObject:firstResponder] ? (int) [allTextFields indexOfObject:firstResponder] : -1; + int nextIndex = (currentIndex + 1) % [allTextFields count]; + + UIResponder *nextResponder = [allTextFields objectAtIndex:nextIndex]; + [nextResponder becomeFirstResponder]; + } + + return YES; + } } return NO; diff --git a/UIKit/Classes/UIKey.h b/UIKit/Classes/UIKey.h index 019c75e1..1311e9e3 100644 --- a/UIKit/Classes/UIKey.h +++ b/UIKit/Classes/UIKey.h @@ -41,6 +41,7 @@ typedef enum { UIKeyTypeRightArrow, UIKeyTypeReturn, UIKeyTypeEnter, + UIKeyTypeTab, UIKeyTypeHome, UIKeyTypeInsert, UIKeyTypeDelete, diff --git a/UIKit/Classes/UIKey.m b/UIKit/Classes/UIKey.m index 7dbed326..53a0013c 100644 --- a/UIKit/Classes/UIKey.m +++ b/UIKit/Classes/UIKey.m @@ -68,6 +68,7 @@ - (UIKeyType)type case NSHomeFunctionKey: return UIKeyTypeHome; case 0x000D: return UIKeyTypeReturn; case 0x0003: return UIKeyTypeEnter; + case NSTabCharacter: return UIKeyTypeTab; } } diff --git a/UIKit/Classes/UITextField.m b/UIKit/Classes/UITextField.m index 2fe1951a..44cab5a7 100644 --- a/UIKit/Classes/UITextField.m +++ b/UIKit/Classes/UITextField.m @@ -529,4 +529,6 @@ - (id)mouseCursorForEvent:(UIEvent *)event return [NSCursor IBeamCursor]; } +- (UITextLayer *)textLayer { return _textLayer; } + @end diff --git a/UIKit/Classes/UITextLayer+Private.h b/UIKit/Classes/UITextLayer+Private.h new file mode 100644 index 00000000..5a8b2a48 --- /dev/null +++ b/UIKit/Classes/UITextLayer+Private.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011, The Iconfactory. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of The Iconfactory nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ICONFACTORY BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@interface UITextLayer(Private) + +- (id)containerView; + +@end + diff --git a/UIKit/Classes/UITextLayer.m b/UIKit/Classes/UITextLayer.m index bf2a42d1..c2eac1c7 100644 --- a/UIKit/Classes/UITextLayer.m +++ b/UIKit/Classes/UITextLayer.m @@ -28,6 +28,7 @@ */ #import "UITextLayer.h" +#import "UITextLayer+Private.h" #import "UIScrollView.h" #import "UICustomNSTextView.h" #import "UICustomNSClipView.h" @@ -436,4 +437,6 @@ - (BOOL)textView:(UICustomNSTextView *)aTextView shouldAcceptKeyDown:(NSEvent *) return ![[UIApplication sharedApplication] _sendGlobalKeyboardNSEvent:event fromScreen:[[containerView window] screen]]; } +- (id)containerView { return self->containerView; } + @end diff --git a/UITextField+Private.h b/UITextField+Private.h new file mode 100644 index 00000000..68330f08 --- /dev/null +++ b/UITextField+Private.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2011, The Iconfactory. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of The Iconfactory nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE ICONFACTORY BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +@interface UITextField(Private) + +- (id)textLayer; + +@end + From b70eb964eed060fa5621ba2da8b28025ec60243d Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Mon, 24 Mar 2014 16:34:52 -0400 Subject: [PATCH 27/39] Adjust the positioning of the red spellcheck error line. --- UIKit/Classes/UICustomNSTextView.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UIKit/Classes/UICustomNSTextView.m b/UIKit/Classes/UICustomNSTextView.m index 6523de5e..1aa00ab3 100644 --- a/UIKit/Classes/UICustomNSTextView.m +++ b/UIKit/Classes/UICustomNSTextView.m @@ -334,7 +334,9 @@ - (void)drawFakeSpellingUnderlinesInRect:(NSRect)rect for (NSUInteger i=0; i Date: Mon, 24 Mar 2014 17:04:34 -0400 Subject: [PATCH 28/39] Add support for disabling spellcheck via setAutocorrectionType. --- UIKit/Classes/UICustomNSTextView.h | 3 +++ UIKit/Classes/UICustomNSTextView.m | 9 ++++++++- UIKit/Classes/UITextField.h | 1 + UIKit/Classes/UITextField.m | 5 ++++- UIKit/Classes/UITextLayer.h | 2 ++ UIKit/Classes/UITextLayer.m | 5 +++++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/UIKit/Classes/UICustomNSTextView.h b/UIKit/Classes/UICustomNSTextView.h index d8f6b749..91ccd5f2 100644 --- a/UIKit/Classes/UICustomNSTextView.h +++ b/UIKit/Classes/UICustomNSTextView.h @@ -28,6 +28,7 @@ */ #import +#import "UITextInputTraits.h" @class CALayer, UICustomNSTextView; @@ -40,10 +41,12 @@ @interface UICustomNSTextView: NSTextView { BOOL secureTextEntry; BOOL isBecomingFirstResponder; + UITextAutocorrectionType autocorrectionType; } - (id)initWithFrame:(NSRect)frame secureTextEntry:(BOOL)isSecure isField:(BOOL)isField; - (void)setSecureTextEntry:(BOOL)isSecure; +- (void)setAutocorrectionType:(UITextAutocorrectionType)type; - (BOOL)reallyBecomeFirstResponder; - (BOOL)reallyResignFirstResponder; diff --git a/UIKit/Classes/UICustomNSTextView.m b/UIKit/Classes/UICustomNSTextView.m index 1aa00ab3..f6932e7f 100644 --- a/UIKit/Classes/UICustomNSTextView.m +++ b/UIKit/Classes/UICustomNSTextView.m @@ -29,6 +29,7 @@ #import "UICustomNSTextView.h" #import "UIBulletGlyphGenerator.h" +#import "UITextInputTraits.h" #import #import #import @@ -82,6 +83,7 @@ - (id)initWithFrame:(NSRect)frame secureTextEntry:(BOOL)isSecure isField:(BOOL)i [self setDisplaysLinkToolTips:NO]; [self setAutomaticDataDetectionEnabled:NO]; [self setSecureTextEntry:isSecure]; + [self setAutocorrectionType:UITextAutocorrectionTypeDefault]; [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; @@ -139,6 +141,11 @@ - (void)setSecureTextEntry:(BOOL)isSecure [self updateStyles]; } +- (void)setAutocorrectionType:(UITextAutocorrectionType)type +{ + autocorrectionType = type; +} + - (BOOL)validateMenuItem:(NSMenuItem *)menuItem { if (secureTextEntry && ([menuItem action] == @selector(copy:) || [menuItem action] == @selector(cut:))) { @@ -275,7 +282,7 @@ - (void)keyDown:(NSEvent *)event - (void)setNeedsFakeSpellCheck { - if ([self isContinuousSpellCheckingEnabled]) { + if ([self isContinuousSpellCheckingEnabled] && self->autocorrectionType != UITextAutocorrectionTypeNo) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(forcedSpellCheck) object:nil]; [self performSelector:@selector(forcedSpellCheck) withObject:nil afterDelay:0.5]; } diff --git a/UIKit/Classes/UITextField.h b/UIKit/Classes/UITextField.h index 9c569090..3d0ed105 100644 --- a/UIKit/Classes/UITextField.h +++ b/UIKit/Classes/UITextField.h @@ -81,6 +81,7 @@ typedef enum { NSString *_placeholder; UITextBorderStyle _borderStyle; CGFloat _minimumFontSize; + UITextAutocorrectionType _autocorrectionType; UIView *_inputAccessoryView; UIView *_inputView; diff --git a/UIKit/Classes/UITextField.m b/UIKit/Classes/UITextField.m index 44cab5a7..2729ea81 100644 --- a/UIKit/Classes/UITextField.m +++ b/UIKit/Classes/UITextField.m @@ -63,6 +63,7 @@ - (id)initWithFrame:(CGRect)frame self.clearButtonMode = UITextFieldViewModeNever; self.leftViewMode = UITextFieldViewModeNever; self.rightViewMode = UITextFieldViewModeNever; + self.autocorrectionType = UITextAutocorrectionTypeDefault; self.opaque = NO; } return self; @@ -326,11 +327,13 @@ - (void)setAutocapitalizationType:(UITextAutocapitalizationType)type - (UITextAutocorrectionType)autocorrectionType { - return UITextAutocorrectionTypeDefault; + return self->_autocorrectionType; } - (void)setAutocorrectionType:(UITextAutocorrectionType)type { + self->_autocorrectionType = type; + [self->_textLayer setAutocorrectionType:type]; } - (BOOL)enablesReturnKeyAutomatically diff --git a/UIKit/Classes/UITextLayer.h b/UIKit/Classes/UITextLayer.h index c6092e0f..65e18f4e 100644 --- a/UIKit/Classes/UITextLayer.h +++ b/UIKit/Classes/UITextLayer.h @@ -30,6 +30,7 @@ #import #import #import "UIStringDrawing.h" +#import "UITextInputTraits.h" @class UICustomNSClipView, UICustomNSTextView, UIColor, UIFont, UIScrollView, UIWindow, UIView; @@ -85,6 +86,7 @@ - (id)initWithContainer:(UIView *)aView isField:(BOOL)isField; - (void)setContentOffset:(CGPoint)contentOffset; +- (void)setAutocorrectionType:(UITextAutocorrectionType)type; - (void)scrollRangeToVisible:(NSRange)range; - (BOOL)becomeFirstResponder; - (BOOL)resignFirstResponder; diff --git a/UIKit/Classes/UITextLayer.m b/UIKit/Classes/UITextLayer.m index c2eac1c7..c9acf43b 100644 --- a/UIKit/Classes/UITextLayer.m +++ b/UIKit/Classes/UITextLayer.m @@ -244,6 +244,11 @@ - (void)setSecureTextEntry:(BOOL)s } } +- (void)setAutocorrectionType:(UITextAutocorrectionType)type +{ + [textView setAutocorrectionType:type]; +} + - (void)setEditable:(BOOL)edit { if (editable != edit) { From ebce2bb565ed039a2253f4137e63a79f4e8ca01d Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 25 Mar 2014 09:22:14 -0400 Subject: [PATCH 29/39] Move UITextField+Private.h into a better location. --- UITextField+Private.h => UIKit/Classes/UITextField+Private.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename UITextField+Private.h => UIKit/Classes/UITextField+Private.h (100%) diff --git a/UITextField+Private.h b/UIKit/Classes/UITextField+Private.h similarity index 100% rename from UITextField+Private.h rename to UIKit/Classes/UITextField+Private.h From 4ed34a7e6b0754920ea39f2faa7288eba3b9145f Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 15 Apr 2014 14:25:14 -0400 Subject: [PATCH 30/39] HACK: Disable setting the mouse cursor requested by -[UIView mouseCursorForEvent:]. --- UIKit/Classes/UIWindow.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/UIKit/Classes/UIWindow.m b/UIKit/Classes/UIWindow.m index af5f20d4..22c03009 100644 --- a/UIKit/Classes/UIWindow.m +++ b/UIKit/Classes/UIWindow.m @@ -370,7 +370,10 @@ - (void)sendEvent:(UIEvent *)event NSCursor *newCursor = [view mouseCursorForEvent:event] ?: [NSCursor arrowCursor]; if ([NSCursor currentCursor] != newCursor) { - [newCursor set]; + // Hack: Disabled by Michael Melanson + // because it was interfering with our use case. + + //[newCursor set]; } [view release]; From 45490abb3005d3d98ee840a7d0b0d5ffe66389da Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 13 May 2014 11:23:39 -0400 Subject: [PATCH 31/39] Show context menu on UIWebView controls in DEBUG builds. --- UIKit/Classes/UIWebView.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/UIKit/Classes/UIWebView.m b/UIKit/Classes/UIWebView.m index 2b6267e1..9ecdb860 100644 --- a/UIKit/Classes/UIWebView.m +++ b/UIKit/Classes/UIWebView.m @@ -239,7 +239,11 @@ - (void)webView:(WebView *)sender makeFirstResponder:(NSResponder *)responder - (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems { +#if DEBUG + return defaultMenuItems; +#else return [NSArray array]; +#endif } - (BOOL)webViewIsResizable:(WebView *)sender From ed5eebc74c8b6216e01c7067d84012c66dac3266 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Tue, 13 May 2014 14:10:02 -0400 Subject: [PATCH 32/39] Add property to UIWebView to control whether to show context menu. Replaces previous commit with a better solution. --- UIKit/Classes/UIWebView.h | 3 +++ UIKit/Classes/UIWebView.m | 12 +++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/UIKit/Classes/UIWebView.h b/UIKit/Classes/UIWebView.h index 35e15f20..cc10cc6d 100644 --- a/UIKit/Classes/UIWebView.h +++ b/UIKit/Classes/UIWebView.h @@ -87,4 +87,7 @@ typedef NSUInteger UIWebViewNavigationType; @property (nonatomic, assign) BOOL mediaPlaybackAllowsAirPlay; @property (nonatomic, assign) BOOL keyboardDisplayRequiresUserAction; +// Chameleon specific +@property (nonatomic, assign) BOOL chameleonAllowContextMenu; + @end diff --git a/UIKit/Classes/UIWebView.m b/UIKit/Classes/UIWebView.m index 9ecdb860..166b8123 100644 --- a/UIKit/Classes/UIWebView.m +++ b/UIKit/Classes/UIWebView.m @@ -45,6 +45,7 @@ - (void)_setLocalStorageDatabasePath:(NSString *)path; @implementation UIWebView @synthesize request=_request, delegate=_delegate, dataDetectorTypes=_dataDetectorTypes, scalesPageToFit=_scalesPageToFit; +@synthesize chameleonAllowContextMenu; - (NSString *)_localStorageDatabasePath { @@ -58,6 +59,7 @@ - (id)initWithFrame:(CGRect)frame { if ((self=[super initWithFrame:frame])) { _scalesPageToFit = NO; + self.chameleonAllowContextMenu = NO; _webView = [(WebView *)[WebView alloc] initWithFrame:NSRectFromCGRect(self.bounds)]; [_webView setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; @@ -239,11 +241,11 @@ - (void)webView:(WebView *)sender makeFirstResponder:(NSResponder *)responder - (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems { -#if DEBUG - return defaultMenuItems; -#else - return [NSArray array]; -#endif + if (self.chameleonAllowContextMenu == YES) { + return defaultMenuItems; + } else { + return [NSArray array]; + } } - (BOOL)webViewIsResizable:(WebView *)sender From 297592df63c554b3e2d6c8dc897095953e8e0812 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 19 Aug 2014 15:05:13 -0400 Subject: [PATCH 33/39] add topViewController property (maps to modalViewController) --- UIKit/Classes/UIViewController.h | 2 ++ UIKit/Classes/UIViewController.m | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/UIKit/Classes/UIViewController.h b/UIKit/Classes/UIViewController.h index 92cfcaa2..50c89d51 100644 --- a/UIKit/Classes/UIViewController.h +++ b/UIKit/Classes/UIViewController.h @@ -124,6 +124,8 @@ typedef enum { @property (nonatomic, assign) UIModalPresentationStyle modalPresentationStyle; @property (nonatomic, assign) UIModalTransitionStyle modalTransitionStyle; // not used right now +@property (nonatomic, readonly) UIViewController *topViewController; + @property (nonatomic, readonly) UIViewController *parentViewController; @property (nonatomic, readonly, retain) UINavigationController *navigationController; @property (nonatomic, readonly, retain) UISplitViewController *splitViewController; diff --git a/UIKit/Classes/UIViewController.m b/UIKit/Classes/UIViewController.m index c73e286d..858663c0 100644 --- a/UIKit/Classes/UIViewController.m +++ b/UIKit/Classes/UIViewController.m @@ -275,6 +275,10 @@ - (void)dismissViewControllerAnimated:(BOOL)animated completion:(void(^)(void))c } } +- (UIViewController *)topViewController +{ + return self.modalViewController; +} - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation From d06029f560f14c558e5503ada3a5e1669cd78c32 Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Tue, 19 Aug 2014 15:08:11 -0400 Subject: [PATCH 34/39] rename topViewController property to presentedViewController --- UIKit/Classes/UIViewController.h | 2 +- UIKit/Classes/UIViewController.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/UIKit/Classes/UIViewController.h b/UIKit/Classes/UIViewController.h index 50c89d51..2f77a390 100644 --- a/UIKit/Classes/UIViewController.h +++ b/UIKit/Classes/UIViewController.h @@ -124,7 +124,7 @@ typedef enum { @property (nonatomic, assign) UIModalPresentationStyle modalPresentationStyle; @property (nonatomic, assign) UIModalTransitionStyle modalTransitionStyle; // not used right now -@property (nonatomic, readonly) UIViewController *topViewController; +@property (nonatomic, readonly) UIViewController *presentedViewController; @property (nonatomic, readonly) UIViewController *parentViewController; @property (nonatomic, readonly, retain) UINavigationController *navigationController; diff --git a/UIKit/Classes/UIViewController.m b/UIKit/Classes/UIViewController.m index 858663c0..1a090c0a 100644 --- a/UIKit/Classes/UIViewController.m +++ b/UIKit/Classes/UIViewController.m @@ -275,7 +275,7 @@ - (void)dismissViewControllerAnimated:(BOOL)animated completion:(void(^)(void))c } } -- (UIViewController *)topViewController +- (UIViewController *)presentedViewController { return self.modalViewController; } From b46825219894ac2215d949b4abd3b28ffd961e78 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Mon, 9 Feb 2015 13:17:13 -0500 Subject: [PATCH 35/39] Replace UITextAlignment with NSTextAlignment. --- Chameleon.podspec | 11 ++--------- UIKit/Classes/UIButton.m | 2 +- UIKit/Classes/UIKit.h | 7 +++++++ UIKit/Classes/UILabel.h | 4 ++-- UIKit/Classes/UILabel.m | 4 ++-- UIKit/Classes/UINavigationBar.m | 2 +- UIKit/Classes/UISegmentedControl.m | 4 ++-- UIKit/Classes/UIStringDrawing.h | 8 +------- UIKit/Classes/UIStringDrawing.m | 12 ++++++------ UIKit/Classes/UITextField.h | 2 +- UIKit/Classes/UITextField.m | 12 ++++++------ UIKit/Classes/UITextLayer.h | 2 +- UIKit/Classes/UITextLayer.m | 21 +++++++-------------- UIKit/Classes/UITextView.h | 2 +- UIKit/Classes/UITextView.m | 16 +++++++++++----- 15 files changed, 51 insertions(+), 58 deletions(-) diff --git a/Chameleon.podspec b/Chameleon.podspec index 0a6fd037..6acff5c8 100644 --- a/Chameleon.podspec +++ b/Chameleon.podspec @@ -10,15 +10,8 @@ Pod::Spec.new do |s| s.platform = :osx, '10.6' s.frameworks = 'IOKit', 'QuartzCore', 'SystemConfiguration', 'AppKit', 'Foundation', 'QTKit', 'WebKit' - s.prefix_header_contents = "// If ARC is not enabled, declare empty ARC directives to supress compiler errors - #ifndef __has_feature - #define __has_feature(x) 0 // Compatibility with non-clang compilers. - #endif - - #if !__has_feature(objc_arc) - #define __unsafe_unretained - #define __bridge - #endif" + s.requires_arc = false + s.compiler_flags = '-fno-objc-arc' s.subspec 'UIKit' do |sb| sb.source_files = 'UIKit/Classes/*.{h,m}' diff --git a/UIKit/Classes/UIButton.m b/UIKit/Classes/UIButton.m index 9cbb4892..97d86874 100644 --- a/UIKit/Classes/UIButton.m +++ b/UIKit/Classes/UIButton.m @@ -78,7 +78,7 @@ - (id)initWithFrame:(CGRect)frame self.opaque = NO; _titleLabel.lineBreakMode = UILineBreakModeMiddleTruncation; _titleLabel.backgroundColor = [UIColor clearColor]; - _titleLabel.textAlignment = UITextAlignmentLeft; + _titleLabel.textAlignment = NSLeftTextAlignment; _titleLabel.shadowOffset = CGSizeZero; [self addSubview:_backgroundImageView]; [self addSubview:_imageView]; diff --git a/UIKit/Classes/UIKit.h b/UIKit/Classes/UIKit.h index 24ab4f36..b810f7fd 100644 --- a/UIKit/Classes/UIKit.h +++ b/UIKit/Classes/UIKit.h @@ -118,3 +118,10 @@ // SystemConfiguration-Helper #define kSCNetworkReachabilityFlagsIsWWAN kSCNetworkReachabilityFlagsConnectionOnDemand + + +#define NSTextAlignmentLeft NSLeftTextAlignment +#define NSTextAlignmentCenter NSCenterTextAlignment +#define NSTextAlignmentRight NSRightTextAlignment +#define NSTextAlignmentJustified NSJustifiedTextAlignment +#define NSTextAlignmentNatural NSNaturalTextAlignment \ No newline at end of file diff --git a/UIKit/Classes/UILabel.h b/UIKit/Classes/UILabel.h index 14673cf9..a9efee35 100644 --- a/UIKit/Classes/UILabel.h +++ b/UIKit/Classes/UILabel.h @@ -40,7 +40,7 @@ UIColor *_highlightedTextColor; UIColor *_shadowColor; CGSize _shadowOffset; - UITextAlignment _textAlignment; + NSTextAlignment _textAlignment; UILineBreakMode _lineBreakMode; BOOL _enabled; NSInteger _numberOfLines; @@ -56,7 +56,7 @@ @property (nonatomic, retain) UIColor *highlightedTextColor; @property (nonatomic, retain) UIColor *shadowColor; @property (nonatomic) CGSize shadowOffset; -@property (nonatomic) UITextAlignment textAlignment; +@property (nonatomic) NSTextAlignment textAlignment; @property (nonatomic) UILineBreakMode lineBreakMode; @property (nonatomic, getter=isEnabled) BOOL enabled; @property (nonatomic) NSInteger numberOfLines; // currently only supports 0 or 1 diff --git a/UIKit/Classes/UILabel.m b/UIKit/Classes/UILabel.m index e930cb1c..7a5282b1 100644 --- a/UIKit/Classes/UILabel.m +++ b/UIKit/Classes/UILabel.m @@ -43,7 +43,7 @@ - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { self.userInteractionEnabled = NO; - self.textAlignment = UITextAlignmentLeft; + self.textAlignment = NSLeftTextAlignment; self.lineBreakMode = UILineBreakModeTailTruncation; self.textColor = [UIColor blackColor]; self.backgroundColor = [UIColor whiteColor]; @@ -114,7 +114,7 @@ - (void)setShadowOffset:(CGSize)newOffset } } -- (void)setTextAlignment:(UITextAlignment)newAlignment +- (void)setTextAlignment:(NSTextAlignment)newAlignment { if (newAlignment != _textAlignment) { _textAlignment = newAlignment; diff --git a/UIKit/Classes/UINavigationBar.m b/UIKit/Classes/UINavigationBar.m index 8b5c98e0..d5add95a 100644 --- a/UIKit/Classes/UINavigationBar.m +++ b/UIKit/Classes/UINavigationBar.m @@ -229,7 +229,7 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: if (!_centerView) { UILabel *titleLabel = [[[UILabel alloc] init] autorelease]; titleLabel.text = topItem.title; - titleLabel.textAlignment = UITextAlignmentCenter; + titleLabel.textAlignment = NSCenterTextAlignment; titleLabel.backgroundColor = [UIColor clearColor]; titleLabel.textColor = [UIColor whiteColor]; titleLabel.font = [UIFont boldSystemFontOfSize:14]; diff --git a/UIKit/Classes/UISegmentedControl.m b/UIKit/Classes/UISegmentedControl.m index ae1cb6fd..84a83d72 100644 --- a/UIKit/Classes/UISegmentedControl.m +++ b/UIKit/Classes/UISegmentedControl.m @@ -205,13 +205,13 @@ - (void)drawRect:(CGRect)frame if (enabled) { [_textShadowColor set]; - [string drawInRect:CGRectOffset(textRect, _textShadowOffset.width, _textShadowOffset.height) withFont:_font lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentCenter]; + [string drawInRect:CGRectOffset(textRect, _textShadowOffset.width, _textShadowOffset.height) withFont:_font lineBreakMode:UILineBreakModeTailTruncation alignment:NSCenterTextAlignment]; [_textColor set]; } else { [_disabledTextColor set]; } - [string drawInRect:textRect withFont:_font lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentCenter]; + [string drawInRect:textRect withFont:_font lineBreakMode:UILineBreakModeTailTruncation alignment:NSCenterTextAlignment]; } // Images diff --git a/UIKit/Classes/UIStringDrawing.h b/UIKit/Classes/UIStringDrawing.h index c8b7d909..831a4e67 100644 --- a/UIKit/Classes/UIStringDrawing.h +++ b/UIKit/Classes/UIStringDrawing.h @@ -38,12 +38,6 @@ typedef enum { UILineBreakModeMiddleTruncation, } UILineBreakMode; -typedef enum { - UITextAlignmentLeft, - UITextAlignmentCenter, - UITextAlignmentRight, -} UITextAlignment; - typedef enum { UIBaselineAdjustmentAlignBaselines, UIBaselineAdjustmentAlignCenters, @@ -67,7 +61,7 @@ NSString *const UITextAttributeTextShadowOffset; - (CGSize)drawAtPoint:(CGPoint)point forWidth:(CGFloat)width withFont:(UIFont *)font fontSize:(CGFloat)fontSize lineBreakMode:(UILineBreakMode)lineBreakMode baselineAdjustment:(UIBaselineAdjustment)baselineAdjustment; - (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font; - (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode; -- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment; +- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode alignment:(NSTextAlignment)alignment; // not yet implemented - (CGSize)sizeWithFont:(UIFont *)font minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode; diff --git a/UIKit/Classes/UIStringDrawing.m b/UIKit/Classes/UIStringDrawing.m index 4b395981..767d9a89 100644 --- a/UIKit/Classes/UIStringDrawing.m +++ b/UIKit/Classes/UIStringDrawing.m @@ -173,7 +173,7 @@ - (CGSize)drawAtPoint:(CGPoint)point forWidth:(CGFloat)width withFont:(UIFont *) return [self drawAtPoint:point forWidth:width withFont:font fontSize:[font pointSize] lineBreakMode:lineBreakMode baselineAdjustment:UIBaselineAdjustmentNone]; } -- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment +- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode alignment:(NSTextAlignment)alignment { CGSize actualSize = CGSizeZero; CFArrayRef lines = CreateCTLinesForString(self,rect.size,font,lineBreakMode,&actualSize); @@ -192,9 +192,9 @@ - (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineB CTLineRef line = CFArrayGetValueAtIndex(lines, lineNumber); float flush; switch (alignment) { - case UITextAlignmentCenter: flush = 0.5; break; - case UITextAlignmentRight: flush = 1; break; - case UITextAlignmentLeft: + case NSCenterTextAlignment: flush = 0.5; break; + case NSRightTextAlignment: flush = 1; break; + case NSLeftTextAlignment: default: flush = 0; break; } @@ -217,12 +217,12 @@ - (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineB - (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font { - return [self drawInRect:rect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; + return [self drawInRect:rect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:NSLeftTextAlignment]; } - (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode { - return [self drawInRect:rect withFont:font lineBreakMode:lineBreakMode alignment:UITextAlignmentLeft]; + return [self drawInRect:rect withFont:font lineBreakMode:lineBreakMode alignment:NSLeftTextAlignment]; } @end diff --git a/UIKit/Classes/UITextField.h b/UIKit/Classes/UITextField.h index 3d0ed105..a3d2634e 100644 --- a/UIKit/Classes/UITextField.h +++ b/UIKit/Classes/UITextField.h @@ -109,7 +109,7 @@ typedef enum { - (void)drawTextInRect:(CGRect)rect; @property (nonatomic, assign) id delegate; -@property (nonatomic, assign) UITextAlignment textAlignment; +@property (nonatomic, assign) NSTextAlignment textAlignment; @property (nonatomic, copy) NSString *placeholder; @property (nonatomic, copy) NSString *text; @property (nonatomic, retain) UIFont *font; diff --git a/UIKit/Classes/UITextField.m b/UIKit/Classes/UITextField.m index 2729ea81..1b1b32d7 100644 --- a/UIKit/Classes/UITextField.m +++ b/UIKit/Classes/UITextField.m @@ -56,7 +56,7 @@ - (id)initWithFrame:(CGRect)frame _textLayer = [[UITextLayer alloc] initWithContainer:self isField:YES]; [self.layer insertSublayer:_textLayer atIndex:0]; - self.textAlignment = UITextAlignmentLeft; + self.textAlignment = NSLeftTextAlignment; self.font = [UIFont systemFontOfSize:17]; self.borderStyle = UITextBorderStyleNone; self.textColor = [UIColor blackColor]; @@ -426,12 +426,12 @@ - (void)setTextColor:(UIColor *)newColor _textLayer.textColor = newColor; } -- (UITextAlignment)textAlignment +- (NSTextAlignment)textAlignment { return _textLayer.textAlignment; } -- (void)setTextAlignment:(UITextAlignment)textAlignment +- (void)setTextAlignment:(NSTextAlignment)textAlignment { _textLayer.textAlignment = textAlignment; } @@ -514,13 +514,13 @@ - (NSString *)description { NSString *textAlignment = @""; switch (self.textAlignment) { - case UITextAlignmentLeft: + case NSLeftTextAlignment: textAlignment = @"Left"; break; - case UITextAlignmentCenter: + case NSCenterTextAlignment: textAlignment = @"Center"; break; - case UITextAlignmentRight: + case NSRightTextAlignment: textAlignment = @"Right"; break; } diff --git a/UIKit/Classes/UITextLayer.h b/UIKit/Classes/UITextLayer.h index 65e18f4e..8056fb10 100644 --- a/UIKit/Classes/UITextLayer.h +++ b/UIKit/Classes/UITextLayer.h @@ -97,6 +97,6 @@ @property (nonatomic, retain) UIFont *font; @property (nonatomic, assign) BOOL editable; @property (nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; -@property (nonatomic, assign) UITextAlignment textAlignment; +@property (nonatomic, assign) NSTextAlignment textAlignment; @end diff --git a/UIKit/Classes/UITextLayer.m b/UIKit/Classes/UITextLayer.m index c9acf43b..d884ba11 100644 --- a/UIKit/Classes/UITextLayer.m +++ b/UIKit/Classes/UITextLayer.m @@ -72,7 +72,7 @@ - (id)initWithContainer:(UIView ", [self className], self, textAlignment, NSStringFromRange(self.selectedRange), (self.editable ? @"YES" : @"NO"), self.textColor, self.font, self.delegate]; } From 4c7d637b6e3cbfc3ab4194b77a2cc173dce47517 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Mon, 9 Feb 2015 14:08:27 -0500 Subject: [PATCH 36/39] Fix up a bug in splash screen positioning. --- UIKit/Classes/UIKitView.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/UIKit/Classes/UIKitView.m b/UIKit/Classes/UIKitView.m index 9e3f1b61..337469fc 100644 --- a/UIKit/Classes/UIKitView.m +++ b/UIKit/Classes/UIKitView.m @@ -308,13 +308,17 @@ - (void)launchApplicationWithDelegate:(id)appDelegate aft if (delay) { UIImage *defaultImage = [UIImage imageNamed:@"Default-Landscape.png"]; UIImageView *defaultImageView = [[[UIImageView alloc] initWithImage:defaultImage] autorelease]; - defaultImageView.contentMode = UIViewContentModeCenter; + defaultImageView.contentMode = UIViewContentModeScaleAspectFill; + defaultImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + defaultImageView.frame = _screen.bounds; UIWindow *defaultWindow = [(UIWindow *)[UIWindow alloc] initWithFrame:_screen.bounds]; defaultWindow.userInteractionEnabled = NO; defaultWindow.screen = _screen; defaultWindow.backgroundColor = [UIColor blackColor]; // dunno.. defaultWindow.opaque = YES; + defaultWindow.autoresizesSubviews = YES; + defaultWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [defaultWindow addSubview:defaultImageView]; [defaultWindow makeKeyAndVisible]; [self performSelector:@selector(_launchApplicationWithDefaultWindow:) withObject:defaultWindow afterDelay:delay]; From d52553a22ef183d81fe4dc7de1b9955820b226e6 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Mon, 9 Feb 2015 14:08:58 -0500 Subject: [PATCH 37/39] Add stub property 'translatesAutoresizingMaskIntoConstraints'. --- UIKit/Classes/UIView.h | 1 + 1 file changed, 1 insertion(+) diff --git a/UIKit/Classes/UIView.h b/UIKit/Classes/UIView.h index 6a3e401e..807a6019 100644 --- a/UIKit/Classes/UIView.h +++ b/UIKit/Classes/UIView.h @@ -207,5 +207,6 @@ typedef NSUInteger UIViewAnimationOptions; @property (nonatomic, getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled; // state is maintained, but it has no effect @property (nonatomic, getter=isExclusiveTouch) BOOL exclusiveTouch; // state is maintained, but it has no effect @property (nonatomic,copy) NSArray *gestureRecognizers; +@property (nonatomic, assign) BOOL translatesAutoresizingMaskIntoConstraints; @end From cbb2d154d3e7eb124b7915483143a3e5b8018b99 Mon Sep 17 00:00:00 2001 From: Michael Melanson Date: Mon, 9 Feb 2015 14:09:54 -0500 Subject: [PATCH 38/39] Fire viewWillAppear delegate method asynchronously --- UIKit/Classes/UIView.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index 636fc41d..9d007f85 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -233,7 +233,9 @@ - (void)addSubview:(UIView *)subview subview->_needsDidAppearOrDisappear = YES;//[self _subviewControllersNeedAppearAndDisappear]; if ([subview _viewController] && subview->_needsDidAppearOrDisappear) { - [[subview _viewController] viewWillAppear:NO]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[subview _viewController] viewWillAppear:NO]; + }); } [subview _willMoveFromWindow:oldWindow toWindow:newWindow]; @@ -268,7 +270,9 @@ - (void)addSubview:(UIView *)subview [self didAddSubview:subview]; if ([subview _viewController] && subview->_needsDidAppearOrDisappear) { - [[subview _viewController] viewDidAppear:NO]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[subview _viewController] viewDidAppear:NO]; + }); } } } From 018bbca395b12839c9fe61020718f65fa5e5fb42 Mon Sep 17 00:00:00 2001 From: Rob Nielsen Date: Tue, 14 Apr 2015 16:54:00 -0400 Subject: [PATCH 39/39] Change containerView from id to UIView* --- UIKit/Classes/UITextLayer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UIKit/Classes/UITextLayer.h b/UIKit/Classes/UITextLayer.h index 8056fb10..26b23751 100644 --- a/UIKit/Classes/UITextLayer.h +++ b/UIKit/Classes/UITextLayer.h @@ -67,7 +67,7 @@ @end @interface UITextLayer : CALayer { - id containerView; + UIView *containerView; BOOL containerCanScroll; UICustomNSTextView *textView; UICustomNSClipView *clipView;