From 8ee93304c8911c6eb5f2d0e7ed5e3ff4b33325fe Mon Sep 17 00:00:00 2001 From: Sean Heber Date: Fri, 16 May 2014 10:19:38 -0500 Subject: [PATCH] Events, ARC, and more MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sorry for everything lumped into one but it’s been a long time and I didn’t do a good job keeping our internal branch (which is stuck in svn) in sync with the this one. I know I know I’m doing it wrong! :P This includes a bunch of modernization of the codebase including a switch to ARC (which many of you have already done). It also includes some rather significant changes to how events get from AppKit to UIKit, gesture recognizers, responder chain changes (attempts to integrate between NSResponder and UIResponder), and probably a bunch of other stuff I’ve forgotten about. Due to a heavy focus on iOS work lately, this code has not been extensively used or tested but it was well past time to get it out there. --- .../AVFoundation.xcodeproj/project.pbxproj | 10 +- .../xcshareddata/AVFoundation.xccheckout | 50 ++ .../AddressBookUI.xcodeproj/project.pbxproj | 13 +- .../xcshareddata/AddressBookUI.xccheckout | 50 ++ .../AssetsLibrary.xcodeproj/project.pbxproj | 12 +- .../xcshareddata/AssetsLibrary.xccheckout | 50 ++ .../BigApple.xcodeproj/project.pbxproj | 15 +- .../xcshareddata/BigApple.xccheckout | 50 ++ .../MultiApple.xcodeproj/project.pbxproj | 15 +- .../xcshareddata/MultiApple.xccheckout | 50 ++ .../NavBarUpdates.xcodeproj/project.pbxproj | 21 +- .../xcshareddata/NavBarUpdates.xccheckout | 50 ++ .../MediaPlayer.xcodeproj/project.pbxproj | 8 +- .../xcshareddata/MediaPlayer.xccheckout | 50 ++ .../Classes/MFMailComposeViewController.h | 9 +- .../Classes/MFMailComposeViewController.m | 1 - MessageUI/MFMessageComposeViewController.h | 12 +- MessageUI/MFMessageComposeViewController.m | 4 - MessageUI/MessageUI.xcodeproj/project.pbxproj | 12 +- .../xcshareddata/MessageUI.xccheckout | 50 ++ MessageUI/MessageUI_Prefix.pch | 10 - StoreKit/StoreKit.xcodeproj/project.pbxproj | 10 +- .../xcshareddata/StoreKit.xccheckout | 50 ++ StoreKit/StoreKit_Prefix.pch | 10 - UIKit/Classes/NSFetchedResultsController.h | 116 ---- UIKit/Classes/NSFetchedResultsController.m | 109 ---- UIKit/Classes/UIAcceleration.h | 9 +- UIKit/Classes/UIAcceleration.m | 1 - UIKit/Classes/UIAccelerometer.h | 8 +- UIKit/Classes/UIAccelerometer.m | 1 - UIKit/Classes/UIAccessibility.h | 11 + UIKit/Classes/UIAccessibility.m | 1 + UIKit/Classes/UIAccessibilityElement.h | 16 +- UIKit/Classes/UIAccessibilityElement.m | 9 - UIKit/Classes/UIAction.h | 9 +- UIKit/Classes/UIAction.m | 3 +- UIKit/Classes/UIActionSheet.h | 28 +- UIKit/Classes/UIActionSheet.m | 35 +- UIKit/Classes/UIActivityIndicatorView.h | 14 +- UIKit/Classes/UIActivityIndicatorView.m | 99 ++- UIKit/Classes/UIAlertView.h | 21 +- UIKit/Classes/UIAlertView.m | 45 +- UIKit/Classes/UIAppearanceInstance.h | 8 +- UIKit/Classes/UIAppearanceInstance.m | 211 +++---- UIKit/Classes/UIAppearanceProperty.h | 16 +- UIKit/Classes/UIAppearanceProperty.m | 88 ++- UIKit/Classes/UIAppearanceProxy.h | 7 +- UIKit/Classes/UIAppearanceProxy.m | 168 +++-- UIKit/Classes/UIApplication.h | 77 ++- UIKit/Classes/UIApplication.m | 482 +++++---------- .../Classes/UIApplicationAppKitIntegration.h | 6 + UIKit/Classes/UIApplicationDelegate.h | 12 +- UIKit/Classes/UIBackgroundTask.h | 7 +- UIKit/Classes/UIBackgroundTask.m | 6 - UIKit/Classes/UIBarButtonItem.h | 33 +- UIKit/Classes/UIBarButtonItem.m | 69 ++- UIKit/Classes/UIBarItem.h | 17 +- UIKit/Classes/UIBarItem.m | 8 +- UIKit/Classes/UIBezierPath.h | 45 +- UIKit/Classes/UIBezierPath.m | 48 +- UIKit/Classes/UIButton.h | 37 +- UIKit/Classes/UIButton.m | 29 +- UIKit/Classes/UIColor.h | 10 +- UIKit/Classes/UIColor.m | 33 +- UIKit/Classes/UIColorRep.h | 5 +- UIKit/Classes/UIColorRep.m | 15 +- UIKit/Classes/UIControl.h | 30 +- UIKit/Classes/UIControl.m | 16 +- UIKit/Classes/UIControlAction.h | 6 +- UIKit/Classes/UIControlAction.m | 2 - UIKit/Classes/UICustomNSClipView.h | 9 +- UIKit/Classes/UICustomNSClipView.m | 20 +- UIKit/Classes/UICustomNSTextView.h | 5 +- UIKit/Classes/UICustomNSTextView.m | 36 +- UIKit/Classes/UIDataDetectors.h | 3 +- UIKit/Classes/UIDatePicker.h | 34 +- UIKit/Classes/UIDatePicker.m | 23 - UIKit/Classes/UIDevice.h | 29 +- UIKit/Classes/UIDevice.m | 9 +- UIKit/Classes/UIEvent.h | 28 +- UIKit/Classes/UIEvent.m | 46 +- UIKit/Classes/UIFont.h | 6 +- UIKit/Classes/UIFont.m | 11 +- UIKit/Classes/UIGestureRecognizer+UIPrivate.h | 8 +- UIKit/Classes/UIGestureRecognizer.h | 25 +- UIKit/Classes/UIGestureRecognizer.m | 188 +++--- UIKit/Classes/UIGestureRecognizerSubclass.h | 4 +- UIKit/Classes/UIGraphics.m | 2 +- UIKit/Classes/UIImage+UIPrivate.m | 1 - UIKit/Classes/UIImage.h | 7 +- UIKit/Classes/UIImage.m | 44 +- UIKit/Classes/UIImageAppKitIntegration.h | 42 ++ UIKit/Classes/UIImageAppKitIntegration.m | 30 +- UIKit/Classes/UIImagePickerController.h | 16 +- UIKit/Classes/UIImagePickerController.m | 8 - UIKit/Classes/UIImageRep.h | 7 +- UIKit/Classes/UIImageRep.m | 39 +- UIKit/Classes/UIImageView+UIPrivate.h | 4 +- UIKit/Classes/UIImageView.h | 18 +- UIKit/Classes/UIImageView.m | 22 +- UIKit/Classes/UIInputController.h | 14 +- UIKit/Classes/UIInputController.m | 28 +- UIKit/Classes/UIInterface.h | 8 +- UIKit/Classes/UIKey.h | 19 +- UIKit/Classes/UIKey.m | 30 +- UIKit/Classes/UIKit.h | 10 +- UIKit/Classes/UIKitView.h | 29 +- UIKit/Classes/UIKitView.m | 581 +++++++++++++----- UIKit/Classes/UILabel.h | 33 +- UIKit/Classes/UILabel.m | 23 +- UIKit/Classes/UILongPressGestureRecognizer.h | 17 +- UIKit/Classes/UILongPressGestureRecognizer.m | 66 +- UIKit/Classes/UIMenuController.h | 15 +- UIKit/Classes/UIMenuController.m | 36 +- UIKit/Classes/UIMenuItem.h | 8 +- UIKit/Classes/UIMenuItem.m | 7 - ...+UIPrivate.h => UINSApplicationDelegate.h} | 7 +- ...onDelegate.h => UINSApplicationDelegate.m} | 27 +- UIKit/Classes/UINSClipView.h | 4 +- UIKit/Classes/UINSClipView.m | 27 +- ...ionBar+UIPrivate.h => UINSResponderShim.h} | 34 +- UIKit/Classes/UINSResponderShim.m | 85 +++ UIKit/Classes/UINavigationBar.h | 42 +- UIKit/Classes/UINavigationBar.m | 178 +++--- UIKit/Classes/UINavigationController.h | 39 +- UIKit/Classes/UINavigationController.m | 485 ++++++++------- UIKit/Classes/UINavigationItem+UIPrivate.h | 15 +- UIKit/Classes/UINavigationItem.h | 24 +- UIKit/Classes/UINavigationItem.m | 120 ++-- UIKit/Classes/UINinePartImage.h | 6 +- UIKit/Classes/UINinePartImage.m | 5 +- UIKit/Classes/UIPageControl.h | 7 +- UIKit/Classes/UIPageControl.m | 1 - UIKit/Classes/UIPanGestureRecognizer.h | 10 +- UIKit/Classes/UIPanGestureRecognizer.m | 71 ++- UIKit/Classes/UIPasteboard.h | 16 +- UIKit/Classes/UIPasteboard.m | 44 +- UIKit/Classes/UIPhotosAlbum.m | 11 +- UIKit/Classes/UIPickerView.h | 16 +- UIKit/Classes/UIPickerView.m | 5 - UIKit/Classes/UIPinchGestureRecognizer.h | 6 +- UIKit/Classes/UIPinchGestureRecognizer.m | 52 +- UIKit/Classes/UIPopoverController.h | 28 +- UIKit/Classes/UIPopoverController.m | 89 +-- UIKit/Classes/UIPopoverNSWindow.h | 4 +- UIKit/Classes/UIPopoverNSWindow.m | 4 +- UIKit/Classes/UIPopoverOverlayNSView.h | 4 +- UIKit/Classes/UIPopoverOverlayNSView.m | 4 +- UIKit/Classes/UIPopoverView.h | 9 +- UIKit/Classes/UIPopoverView.m | 26 +- UIKit/Classes/UIProgressView.h | 14 +- UIKit/Classes/UIProgressView.m | 12 +- UIKit/Classes/UIResponder.h | 37 +- UIKit/Classes/UIResponder.m | 109 +++- UIKit/Classes/UIResponderAppKitIntegration.h | 35 +- UIKit/Classes/UIResponderAppKitIntegration.m | 22 +- UIKit/Classes/UIRotationGestureRecognizer.h | 6 +- UIKit/Classes/UIRotationGestureRecognizer.m | 1 - UIKit/Classes/UIScreen+UIPrivate.h | 8 +- UIKit/Classes/UIScreen.h | 16 +- UIKit/Classes/UIScreen.m | 84 +-- UIKit/Classes/UIScreenAppKitIntegration.h | 14 +- UIKit/Classes/UIScreenAppKitIntegration.m | 13 +- UIKit/Classes/UIScreenMode.h | 7 +- UIKit/Classes/UIScreenMode.m | 3 +- UIKit/Classes/UIScrollView.h | 66 +- UIKit/Classes/UIScrollView.m | 202 +++--- UIKit/Classes/UIScrollViewAnimation.h | 10 +- UIKit/Classes/UIScrollViewAnimation.m | 9 +- .../UIScrollViewAnimationDeceleration.h | 8 +- .../UIScrollViewAnimationDeceleration.m | 84 +-- UIKit/Classes/UIScrollViewAnimationScroll.h | 16 +- UIKit/Classes/UIScrollViewAnimationScroll.m | 18 +- .../Classes/UIScrollWheelGestureRecognizer.h | 7 +- .../Classes/UIScrollWheelGestureRecognizer.m | 30 +- UIKit/Classes/UIScroller.h | 15 +- UIKit/Classes/UIScroller.m | 15 +- UIKit/Classes/UISearchBar.h | 15 +- UIKit/Classes/UISearchBar.m | 8 +- UIKit/Classes/UISearchDisplayController.h | 19 +- UIKit/Classes/UISearchDisplayController.m | 17 +- UIKit/Classes/UISegmentedControl.h | 65 +- UIKit/Classes/UISegmentedControl.m | 86 +-- UIKit/Classes/UISlider.h | 20 +- UIKit/Classes/UISlider.m | 46 +- UIKit/Classes/UISplitViewController.h | 14 +- UIKit/Classes/UISplitViewController.m | 28 +- UIKit/Classes/UIStringDrawing.h | 20 +- UIKit/Classes/UISwipeGestureRecognizer.h | 14 +- UIKit/Classes/UISwipeGestureRecognizer.m | 27 +- UIKit/Classes/UISwitch.h | 6 +- UIKit/Classes/UISwitch.m | 1 - UIKit/Classes/UITabBar.h | 16 +- UIKit/Classes/UITabBar.m | 15 +- UIKit/Classes/UITabBarController.h | 9 +- UIKit/Classes/UITabBarController.m | 10 - UIKit/Classes/UITabBarItem.h | 10 +- UIKit/Classes/UITabBarItem.m | 7 - UIKit/Classes/UITableView.h | 72 +-- UIKit/Classes/UITableView.m | 303 +++++---- UIKit/Classes/UITableViewCell.h | 61 +- UIKit/Classes/UITableViewCell.m | 32 +- UIKit/Classes/UITableViewCellSeparator.h | 6 +- UIKit/Classes/UITableViewCellSeparator.m | 13 +- UIKit/Classes/UITableViewController.h | 11 +- UIKit/Classes/UITableViewController.m | 8 +- UIKit/Classes/UITableViewSection.h | 16 +- UIKit/Classes/UITableViewSection.m | 16 +- UIKit/Classes/UITableViewSectionLabel.m | 2 +- UIKit/Classes/UITapGestureRecognizer.h | 7 +- UIKit/Classes/UITapGestureRecognizer.m | 1 - UIKit/Classes/UITextField.h | 71 +-- UIKit/Classes/UITextField.m | 114 +++- ...BlockAnimationDelegate.m => UITextInput.h} | 38 +- .../{UIKey+UIPrivate.h => UITextInput.m} | 10 +- UIKit/Classes/UITextInputTraits.h | 22 +- UIKit/Classes/UITextLayer.h | 24 +- UIKit/Classes/UITextLayer.m | 228 +++---- UIKit/Classes/UITextView.h | 38 +- UIKit/Classes/UITextView.m | 62 +- UIKit/Classes/UIThreePartImage.h | 6 +- UIKit/Classes/UIThreePartImage.m | 5 +- UIKit/Classes/UIToolbar.h | 19 +- UIKit/Classes/UIToolbar.m | 67 +- UIKit/Classes/UIToolbarButton.h | 3 +- UIKit/Classes/UITouch+UIPrivate.h | 27 +- UIKit/Classes/UITouch.h | 43 +- UIKit/Classes/UITouch.m | 205 +++--- .../{UIEvent+UIPrivate.h => UITouchEvent.h} | 41 +- ...Application+UIPrivate.h => UITouchEvent.m} | 65 +- UIKit/Classes/UITransitionView.h | 65 -- UIKit/Classes/UITransitionView.m | 136 ---- UIKit/Classes/UIView.h | 61 +- UIKit/Classes/UIView.m | 311 ++++++---- UIKit/Classes/UIViewAdapter.h | 11 +- UIKit/Classes/UIViewAdapter.m | 22 +- UIKit/Classes/UIViewAnimationGroup.h | 64 +- UIKit/Classes/UIViewAnimationGroup.m | 303 +++++---- UIKit/Classes/UIViewController.h | 80 +-- UIKit/Classes/UIViewController.m | 276 ++++++++- .../UIViewControllerAppKitIntegration.h | 70 +++ UIKit/Classes/UIWebView.h | 28 +- UIKit/Classes/UIWebView.m | 25 +- UIKit/Classes/UIWindow.h | 24 +- UIKit/Classes/UIWindow.m | 319 +++++++--- UIKit/UIKit.xcodeproj/project.pbxproj | 122 ++-- .../xcshareddata/UIKit.xccheckout | 50 ++ UIKit/UIKit_Prefix.pch | 10 - 248 files changed, 5491 insertions(+), 5227 deletions(-) create mode 100644 AVFoundation/AVFoundation.xcodeproj/project.xcworkspace/xcshareddata/AVFoundation.xccheckout create mode 100644 AddressBookUI/AddressBookUI.xcodeproj/project.xcworkspace/xcshareddata/AddressBookUI.xccheckout create mode 100644 AssetsLibrary/AssetsLibrary.xcodeproj/project.xcworkspace/xcshareddata/AssetsLibrary.xccheckout create mode 100644 Examples/BigApple/BigApple.xcodeproj/project.xcworkspace/xcshareddata/BigApple.xccheckout create mode 100644 Examples/MultiApple/MultiApple.xcodeproj/project.xcworkspace/xcshareddata/MultiApple.xccheckout create mode 100644 Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.xcworkspace/xcshareddata/NavBarUpdates.xccheckout create mode 100644 MediaPlayer/MediaPlayer.xcodeproj/project.xcworkspace/xcshareddata/MediaPlayer.xccheckout create mode 100644 MessageUI/MessageUI.xcodeproj/project.xcworkspace/xcshareddata/MessageUI.xccheckout create mode 100644 StoreKit/StoreKit.xcodeproj/project.xcworkspace/xcshareddata/StoreKit.xccheckout delete mode 100644 UIKit/Classes/NSFetchedResultsController.h delete mode 100644 UIKit/Classes/NSFetchedResultsController.m rename UIKit/Classes/{UIViewController+UIPrivate.h => UINSApplicationDelegate.h} (88%) rename UIKit/Classes/{UIViewBlockAnimationDelegate.h => UINSApplicationDelegate.m} (60%) rename UIKit/Classes/{UINavigationBar+UIPrivate.h => UINSResponderShim.h} (54%) create mode 100644 UIKit/Classes/UINSResponderShim.m rename UIKit/Classes/{UIViewBlockAnimationDelegate.m => UITextInput.h} (62%) rename UIKit/Classes/{UIKey+UIPrivate.h => UITextInput.m} (90%) rename UIKit/Classes/{UIEvent+UIPrivate.h => UITouchEvent.h} (53%) rename UIKit/Classes/{UIApplication+UIPrivate.h => UITouchEvent.m} (57%) delete mode 100644 UIKit/Classes/UITransitionView.h delete mode 100644 UIKit/Classes/UITransitionView.m create mode 100644 UIKit/Classes/UIViewControllerAppKitIntegration.h create mode 100644 UIKit/UIKit.xcodeproj/project.xcworkspace/xcshareddata/UIKit.xccheckout diff --git a/AVFoundation/AVFoundation.xcodeproj/project.pbxproj b/AVFoundation/AVFoundation.xcodeproj/project.pbxproj index 4bef6d31..9b86cb55 100644 --- a/AVFoundation/AVFoundation.xcodeproj/project.pbxproj +++ b/AVFoundation/AVFoundation.xcodeproj/project.pbxproj @@ -140,7 +140,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0510; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "AVFoundation" */; compatibilityVersion = "Xcode 3.2"; @@ -202,7 +202,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = AVFoundation; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -222,7 +221,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = AVFoundation; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Release; @@ -230,13 +228,12 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; @@ -245,13 +242,12 @@ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; PROVISIONING_PROFILE = ""; SDKROOT = macosx; }; diff --git a/AVFoundation/AVFoundation.xcodeproj/project.xcworkspace/xcshareddata/AVFoundation.xccheckout b/AVFoundation/AVFoundation.xcodeproj/project.xcworkspace/xcshareddata/AVFoundation.xccheckout new file mode 100644 index 00000000..b792d443 --- /dev/null +++ b/AVFoundation/AVFoundation.xcodeproj/project.xcworkspace/xcshareddata/AVFoundation.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + D07BFBE5-D22F-4E7C-8EC3-D1129799E6A7 + IDESourceControlProjectName + AVFoundation + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + AVFoundation/AVFoundation.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/AVFoundation/AVFoundation.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/AddressBookUI/AddressBookUI.xcodeproj/project.pbxproj b/AddressBookUI/AddressBookUI.xcodeproj/project.pbxproj index 2c79c466..9f809cfc 100644 --- a/AddressBookUI/AddressBookUI.xcodeproj/project.pbxproj +++ b/AddressBookUI/AddressBookUI.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -166,8 +166,11 @@ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "AddressBookUI" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -278,26 +281,24 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Debug; }; 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Release; }; diff --git a/AddressBookUI/AddressBookUI.xcodeproj/project.xcworkspace/xcshareddata/AddressBookUI.xccheckout b/AddressBookUI/AddressBookUI.xcodeproj/project.xcworkspace/xcshareddata/AddressBookUI.xccheckout new file mode 100644 index 00000000..73a9ff5b --- /dev/null +++ b/AddressBookUI/AddressBookUI.xcodeproj/project.xcworkspace/xcshareddata/AddressBookUI.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 9F3968B1-EE4C-4FC9-9142-CB68E7E1F3AC + IDESourceControlProjectName + AddressBookUI + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + AddressBookUI/AddressBookUI.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/AddressBookUI/AddressBookUI.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/AssetsLibrary/AssetsLibrary.xcodeproj/project.pbxproj b/AssetsLibrary/AssetsLibrary.xcodeproj/project.pbxproj index 250c53bf..daf140b8 100644 --- a/AssetsLibrary/AssetsLibrary.xcodeproj/project.pbxproj +++ b/AssetsLibrary/AssetsLibrary.xcodeproj/project.pbxproj @@ -161,7 +161,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0510; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "AssetsLibrary" */; compatibilityVersion = "Xcode 3.2"; @@ -227,7 +227,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = AssetsLibrary; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -248,7 +247,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = AssetsLibrary; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Release; @@ -256,13 +254,12 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; @@ -271,13 +268,12 @@ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; + CODE_SIGN_IDENTITY = "Developer ID Application: The Iconfactory"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; PROVISIONING_PROFILE = ""; SDKROOT = macosx; }; diff --git a/AssetsLibrary/AssetsLibrary.xcodeproj/project.xcworkspace/xcshareddata/AssetsLibrary.xccheckout b/AssetsLibrary/AssetsLibrary.xcodeproj/project.xcworkspace/xcshareddata/AssetsLibrary.xccheckout new file mode 100644 index 00000000..0d001db3 --- /dev/null +++ b/AssetsLibrary/AssetsLibrary.xcodeproj/project.xcworkspace/xcshareddata/AssetsLibrary.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 325CD246-7DA7-4A70-BA15-8AA78CD07E08 + IDESourceControlProjectName + AssetsLibrary + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + AssetsLibrary/AssetsLibrary.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/AssetsLibrary/AssetsLibrary.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/Examples/BigApple/BigApple.xcodeproj/project.pbxproj b/Examples/BigApple/BigApple.xcodeproj/project.pbxproj index 89bb9fb9..af480485 100644 --- a/Examples/BigApple/BigApple.xcodeproj/project.pbxproj +++ b/Examples/BigApple/BigApple.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -211,8 +211,11 @@ /* Begin PBXProject section */ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "BigApple" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -320,6 +323,7 @@ INFOPLIST_FILE = "BigApple-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; PRODUCT_NAME = BigApple; + SDKROOT = macosx; }; name = Debug; }; @@ -339,32 +343,31 @@ INFOPLIST_FILE = "BigApple-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; PRODUCT_NAME = BigApple; + SDKROOT = macosx; }; name = Release; }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Release; }; diff --git a/Examples/BigApple/BigApple.xcodeproj/project.xcworkspace/xcshareddata/BigApple.xccheckout b/Examples/BigApple/BigApple.xcodeproj/project.xcworkspace/xcshareddata/BigApple.xccheckout new file mode 100644 index 00000000..18129e6f --- /dev/null +++ b/Examples/BigApple/BigApple.xcodeproj/project.xcworkspace/xcshareddata/BigApple.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 014C1F5D-2A9E-449E-85EA-21CA406C7C86 + IDESourceControlProjectName + BigApple + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + Examples/BigApple/BigApple.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/Examples/BigApple/BigApple.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/Examples/MultiApple/MultiApple.xcodeproj/project.pbxproj b/Examples/MultiApple/MultiApple.xcodeproj/project.pbxproj index 248bd6d5..21a61483 100644 --- a/Examples/MultiApple/MultiApple.xcodeproj/project.pbxproj +++ b/Examples/MultiApple/MultiApple.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 45; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ @@ -298,8 +298,11 @@ /* Begin PBXProject section */ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0510; + }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "MultiApple" */; - compatibilityVersion = "Xcode 3.1"; + compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( @@ -499,7 +502,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DSTROOT = "/tmp/$(PROJECT_NAME).dst"; @@ -537,7 +539,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -575,26 +576,24 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Debug; }; 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Release; }; diff --git a/Examples/MultiApple/MultiApple.xcodeproj/project.xcworkspace/xcshareddata/MultiApple.xccheckout b/Examples/MultiApple/MultiApple.xcodeproj/project.xcworkspace/xcshareddata/MultiApple.xccheckout new file mode 100644 index 00000000..03c2d0a0 --- /dev/null +++ b/Examples/MultiApple/MultiApple.xcodeproj/project.xcworkspace/xcshareddata/MultiApple.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + FBBFB75C-FE54-46A5-ACD2-594A4A0973EE + IDESourceControlProjectName + MultiApple + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + Examples/MultiApple/MultiApple.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/Examples/MultiApple/MultiApple.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.pbxproj b/Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.pbxproj index 8ae79a00..414453a8 100644 --- a/Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.pbxproj +++ b/Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.pbxproj @@ -188,6 +188,7 @@ 38E523B81339731100E041B3 /* Project object */ = { isa = PBXProject; attributes = { + LastUpgradeCheck = 0510; ORGANIZATIONNAME = "XPlatform Inc"; }; buildConfigurationList = 38E523BB1339731100E041B3 /* Build configuration list for PBXProject "NavBarUpdates" */; @@ -289,7 +290,12 @@ 38E523DD1339731100E041B3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; @@ -297,6 +303,9 @@ GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = YES; @@ -307,11 +316,19 @@ 38E523DE1339731100E041B3 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = macosx; diff --git a/Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.xcworkspace/xcshareddata/NavBarUpdates.xccheckout b/Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.xcworkspace/xcshareddata/NavBarUpdates.xccheckout new file mode 100644 index 00000000..7bb718c1 --- /dev/null +++ b/Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.xcworkspace/xcshareddata/NavBarUpdates.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 337C535E-8A84-4C65-B4DE-C440FF9F5D7A + IDESourceControlProjectName + NavBarUpdates + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + Examples/NavBarUpdates/NavBarUpdates.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/Examples/NavBarUpdates/NavBarUpdates.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/MediaPlayer/MediaPlayer.xcodeproj/project.pbxproj b/MediaPlayer/MediaPlayer.xcodeproj/project.pbxproj index 2c2a264a..b8a43e35 100644 --- a/MediaPlayer/MediaPlayer.xcodeproj/project.pbxproj +++ b/MediaPlayer/MediaPlayer.xcodeproj/project.pbxproj @@ -13,8 +13,8 @@ 14EFB1BB1211DB5300D19B0C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14EFB1BA1211DB5300D19B0C /* Cocoa.framework */; }; 4C1677D913C70F1A00814195 /* MPMoviePlayerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1677D713C70F1900814195 /* MPMoviePlayerController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4C1677DA13C70F1A00814195 /* MPMoviePlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1677D813C70F1900814195 /* MPMoviePlayerController.m */; }; - 4C16781613C71E4900814195 /* MPMediaPlayback.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C16781513C71E4900814195 /* MPMediaPlayback.h */; }; - 4C16781A13C71E6200814195 /* UIInternalMovieView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C16781813C71E6200814195 /* UIInternalMovieView.h */; }; + 4C16781613C71E4900814195 /* MPMediaPlayback.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C16781513C71E4900814195 /* MPMediaPlayback.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4C16781A13C71E6200814195 /* UIInternalMovieView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C16781813C71E6200814195 /* UIInternalMovieView.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4C16781B13C71E6200814195 /* UIInternalMovieView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C16781913C71E6200814195 /* UIInternalMovieView.m */; }; 4C16787D13C71FB900814195 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C16787C13C71FB900814195 /* UIKit.framework */; }; 4C16789F13C7206500814195 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C16789E13C7206500814195 /* QTKit.framework */; }; @@ -191,7 +191,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; + LastUpgradeCheck = 0510; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "MediaPlayer" */; compatibilityVersion = "Xcode 3.2"; @@ -306,7 +306,6 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; @@ -321,7 +320,6 @@ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; diff --git a/MediaPlayer/MediaPlayer.xcodeproj/project.xcworkspace/xcshareddata/MediaPlayer.xccheckout b/MediaPlayer/MediaPlayer.xcodeproj/project.xcworkspace/xcshareddata/MediaPlayer.xccheckout new file mode 100644 index 00000000..08ea7606 --- /dev/null +++ b/MediaPlayer/MediaPlayer.xcodeproj/project.xcworkspace/xcshareddata/MediaPlayer.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 25E1A0F8-8F0F-446A-BECC-FE2996734ECD + IDESourceControlProjectName + MediaPlayer + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + MediaPlayer/MediaPlayer.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/MediaPlayer/MediaPlayer.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/MessageUI/Classes/MFMailComposeViewController.h b/MessageUI/Classes/MFMailComposeViewController.h index 0fc059f4..8b7bc319 100644 --- a/MessageUI/Classes/MFMailComposeViewController.h +++ b/MessageUI/Classes/MFMailComposeViewController.h @@ -44,11 +44,7 @@ typedef enum MFMailComposeResult MFMailComposeResult; - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error; @end -@interface MFMailComposeViewController : UINavigationController { -@private - __unsafe_unretained id _mailComposeDelegate; -} - +@interface MFMailComposeViewController : UINavigationController + (BOOL)canSendMail; - (void)setSubject:(NSString*)subject; @@ -58,6 +54,5 @@ typedef enum MFMailComposeResult MFMailComposeResult; - (void)setBccRecipients:(NSArray*)bccRecipients; - (void)addAttachmentData:(NSData*)attachment mimeType:(NSString*)mimeType fileName:(NSString*)filename; -@property (nonatomic,assign) id mailComposeDelegate; - +@property (nonatomic, assign) id mailComposeDelegate; @end diff --git a/MessageUI/Classes/MFMailComposeViewController.m b/MessageUI/Classes/MFMailComposeViewController.m index 985a373c..61308c96 100644 --- a/MessageUI/Classes/MFMailComposeViewController.m +++ b/MessageUI/Classes/MFMailComposeViewController.m @@ -30,7 +30,6 @@ #import "MFMailComposeViewController.h" @implementation MFMailComposeViewController -@synthesize mailComposeDelegate=_mailComposeDelegate; + (BOOL)canSendMail { diff --git a/MessageUI/MFMessageComposeViewController.h b/MessageUI/MFMessageComposeViewController.h index ccd18f42..56f5cd9f 100644 --- a/MessageUI/MFMessageComposeViewController.h +++ b/MessageUI/MFMessageComposeViewController.h @@ -42,18 +42,12 @@ enum MessageComposeResult { }; typedef enum MessageComposeResult MessageComposeResult; -@interface MFMessageComposeViewController : NSObject { - __unsafe_unretained id _messageComposeDelegate; - NSArray *_recipients; - NSString *_body; -} - +@interface MFMessageComposeViewController : NSObject + (BOOL)canSendText; @property (nonatomic, assign) id messageComposeDelegate; -@property(nonatomic,copy) NSArray *recipients; -@property(nonatomic,copy) NSString *body; - +@property(nonatomic, copy) NSArray *recipients; +@property(nonatomic, copy) NSString *body; @end diff --git a/MessageUI/MFMessageComposeViewController.m b/MessageUI/MFMessageComposeViewController.m index 8c23660d..5375dec6 100644 --- a/MessageUI/MFMessageComposeViewController.m +++ b/MessageUI/MFMessageComposeViewController.m @@ -39,10 +39,6 @@ @implementation MFMessageComposeViewController -@synthesize messageComposeDelegate = _messageComposeDelegate; -@synthesize recipients = _recipients; -@synthesize body = _body; - + (BOOL)canSendText { return NO; // most likely we can't send messages on a mac ;) } diff --git a/MessageUI/MessageUI.xcodeproj/project.pbxproj b/MessageUI/MessageUI.xcodeproj/project.pbxproj index 243474ad..c4d0e39e 100644 --- a/MessageUI/MessageUI.xcodeproj/project.pbxproj +++ b/MessageUI/MessageUI.xcodeproj/project.pbxproj @@ -187,7 +187,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0510; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "MessageUI" */; compatibilityVersion = "Xcode 3.2"; @@ -286,7 +286,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = MessageUI; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -308,7 +307,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = MessageUI; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Release; @@ -316,13 +314,12 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; @@ -331,13 +328,12 @@ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; + CODE_SIGN_IDENTITY = "Developer ID Application: The Iconfactory"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; PROVISIONING_PROFILE = ""; SDKROOT = macosx; }; diff --git a/MessageUI/MessageUI.xcodeproj/project.xcworkspace/xcshareddata/MessageUI.xccheckout b/MessageUI/MessageUI.xcodeproj/project.xcworkspace/xcshareddata/MessageUI.xccheckout new file mode 100644 index 00000000..7ccac3ca --- /dev/null +++ b/MessageUI/MessageUI.xcodeproj/project.xcworkspace/xcshareddata/MessageUI.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 0B0E74CD-B913-4D2E-BAD0-73F7E73D7985 + IDESourceControlProjectName + MessageUI + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + MessageUI/MessageUI.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/MessageUI/MessageUI.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/MessageUI/MessageUI_Prefix.pch b/MessageUI/MessageUI_Prefix.pch index 73ffda54..a9ca302e 100644 --- a/MessageUI/MessageUI_Prefix.pch +++ b/MessageUI/MessageUI_Prefix.pch @@ -30,13 +30,3 @@ #ifdef __OBJC__ #import #endif - -// 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 diff --git a/StoreKit/StoreKit.xcodeproj/project.pbxproj b/StoreKit/StoreKit.xcodeproj/project.pbxproj index 7fb2d99c..91a7ded2 100644 --- a/StoreKit/StoreKit.xcodeproj/project.pbxproj +++ b/StoreKit/StoreKit.xcodeproj/project.pbxproj @@ -175,7 +175,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0450; + LastUpgradeCheck = 0500; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "StoreKit" */; compatibilityVersion = "Xcode 3.2"; @@ -274,13 +274,12 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; @@ -289,13 +288,12 @@ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; + CODE_SIGN_IDENTITY = "Developer ID Application: The Iconfactory"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; PROVISIONING_PROFILE = ""; SDKROOT = macosx; }; diff --git a/StoreKit/StoreKit.xcodeproj/project.xcworkspace/xcshareddata/StoreKit.xccheckout b/StoreKit/StoreKit.xcodeproj/project.xcworkspace/xcshareddata/StoreKit.xccheckout new file mode 100644 index 00000000..5be8e98e --- /dev/null +++ b/StoreKit/StoreKit.xcodeproj/project.xcworkspace/xcshareddata/StoreKit.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 7123AA42-C57B-4F08-87C2-5C3ADE24923A + IDESourceControlProjectName + StoreKit + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + StoreKit/StoreKit.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/StoreKit/StoreKit.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/StoreKit/StoreKit_Prefix.pch b/StoreKit/StoreKit_Prefix.pch index 73ffda54..a9ca302e 100644 --- a/StoreKit/StoreKit_Prefix.pch +++ b/StoreKit/StoreKit_Prefix.pch @@ -30,13 +30,3 @@ #ifdef __OBJC__ #import #endif - -// 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 diff --git a/UIKit/Classes/NSFetchedResultsController.h b/UIKit/Classes/NSFetchedResultsController.h deleted file mode 100644 index c17d8541..00000000 --- a/UIKit/Classes/NSFetchedResultsController.h +++ /dev/null @@ -1,116 +0,0 @@ -// -// NSFetchedResultsController.h -// UIKit -// -// Created by Peter Steinberger on 23.03.11. -// -/* - * 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. - */ - - -#import -#import - -//#ifdef NSCoreDataVersionNumber10_5 -@protocol NSFetchedResultsControllerDelegate; - -@class NSFetchRequest; -@class NSManagedObjectContext; - - -@interface NSFetchedResultsController : NSObject { - __unsafe_unretained id _delegate; - NSFetchRequest *_fetchRequest; - NSManagedObjectContext *_managedObjectContext; - NSArray *_fetchedObjects; // we don't yet support sections! - - // stubs - NSString *_sectionNameKeyPath; - NSString *_sectionNameKey; - NSString *_cacheName; -} - -- (id)initWithFetchRequest:(NSFetchRequest *)fetchRequest managedObjectContext: (NSManagedObjectContext *)context sectionNameKeyPath:(NSString *)sectionNameKeyPath cacheName:(NSString *)name; - -- (BOOL)performFetch:(NSError **)error; - -@property (nonatomic, readonly) NSFetchRequest *fetchRequest; -@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext; -@property (nonatomic, readonly) NSString *sectionNameKeyPath; -@property (nonatomic, readonly) NSString *cacheName; -@property(nonatomic, assign) id delegate; -+ (void)deleteCacheWithName:(NSString *)name; - -// accessing objects -@property (nonatomic, readonly) NSArray *fetchedObjects; -- (id)objectAtIndexPath:(NSIndexPath *)indexPath; -- (NSIndexPath *)indexPathForObject:(id)object; - -- (NSString *)sectionIndexTitleForSectionName:(NSString *)sectionName; -@property (nonatomic, readonly) NSArray *sectionIndexTitles; -@property (nonatomic, readonly) NSArray *sections; -- (NSInteger)sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)sectionIndex; - -@end - - -@protocol NSFetchedResultsSectionInfo - -@property (nonatomic, readonly) NSString *name; -@property (nonatomic, readonly) NSString *indexTitle; -@property (nonatomic, readonly) NSUInteger numberOfObjects; -@property (nonatomic, readonly) NSArray *objects; - -@end - -@protocol NSFetchedResultsControllerDelegate - -enum { - NSFetchedResultsChangeInsert = 1, - NSFetchedResultsChangeDelete = 2, - NSFetchedResultsChangeMove = 3, - NSFetchedResultsChangeUpdate = 4 - -}; -typedef NSUInteger NSFetchedResultsChangeType; - -@optional - -- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath; - -- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type; - -- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller; -- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller; - -- (NSString *)controller:(NSFetchedResultsController *)controller sectionIndexTitleForSectionName:(NSString *)sectionName; - -@end - -//#endif diff --git a/UIKit/Classes/NSFetchedResultsController.m b/UIKit/Classes/NSFetchedResultsController.m deleted file mode 100644 index 7ceaa3ff..00000000 --- a/UIKit/Classes/NSFetchedResultsController.m +++ /dev/null @@ -1,109 +0,0 @@ -// -// NSFetchedResultsController.m -// UIKit -// -// Created by Peter Steinberger on 23.03.11. -// -/* - * 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. - */ - -#import "NSFetchedResultsController.h" - -//#ifdef NSCoreDataVersionNumber10_5 - -#import "NSIndexPath+UITableView.h" - -@implementation NSFetchedResultsController - -@synthesize delegate = _delegate; -@synthesize fetchRequest = _fetchRequest; -@synthesize managedObjectContext = _managedObjectContext; -@synthesize fetchedObjects = _fetchedObjects; -@synthesize cacheName = _cacheName, sectionNameKeyPath = _sectionNameKeyPath; - -- (id)initWithFetchRequest:(NSFetchRequest *)fetchRequest managedObjectContext: (NSManagedObjectContext *)context sectionNameKeyPath:(NSString *)sectionNameKeyPath cacheName:(NSString *)name { - if ((self = [super init])) { - _fetchRequest = [fetchRequest retain]; - _managedObjectContext = [context retain]; - } - return self; -} - -- (void)dealloc { - _delegate = nil; - [_fetchRequest release]; - [_managedObjectContext release]; - [_fetchedObjects release]; - [super dealloc]; -} - -- (BOOL)performFetch:(NSError **)error { - [_fetchedObjects release]; - _fetchedObjects = [[_managedObjectContext executeFetchRequest:_fetchRequest error:error] retain]; - - return YES; -} - -- (id)objectAtIndexPath:(NSIndexPath *)indexPath { - return [_fetchedObjects objectAtIndex:indexPath.row]; -} - -- (NSIndexPath *)indexPathForObject:(id)object { - NSUInteger objectIndex = [_fetchedObjects indexOfObject:object]; - return [NSIndexPath indexPathForRow:objectIndex inSection:0]; -} - -// stubs - -+ (void)deleteCacheWithName:(NSString *)name { - // stub -} - - -- (NSString *)sectionIndexTitleForSectionName:(NSString *)sectionName { - return @"UNIMPLEMENTED"; -} - -- (NSArray *)sectionIndexTitles { - // stub - return [NSArray array]; -} - -- (NSArray *)sections { - // stub - return [NSArray array]; -} - -- (NSInteger)sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)sectionIndex { - return 0; -} - -@end - -//#endif diff --git a/UIKit/Classes/UIAcceleration.h b/UIKit/Classes/UIAcceleration.h index 6d09c1e8..3b806754 100644 --- a/UIKit/Classes/UIAcceleration.h +++ b/UIKit/Classes/UIAcceleration.h @@ -31,16 +31,9 @@ typedef double UIAccelerationValue; -@interface UIAcceleration : NSObject { - UIAccelerationValue _x; - UIAccelerationValue _y; - UIAccelerationValue _z; - NSTimeInterval _timestamp; -} - +@interface UIAcceleration : NSObject @property (nonatomic, readonly) UIAccelerationValue x; @property (nonatomic, readonly) UIAccelerationValue y; @property (nonatomic, readonly) UIAccelerationValue z; @property (nonatomic, readonly) NSTimeInterval timestamp; - @end diff --git a/UIKit/Classes/UIAcceleration.m b/UIKit/Classes/UIAcceleration.m index 5f9571d7..8ae1d8f0 100644 --- a/UIKit/Classes/UIAcceleration.m +++ b/UIKit/Classes/UIAcceleration.m @@ -30,5 +30,4 @@ #import "UIAcceleration.h" @implementation UIAcceleration -@synthesize x=_x, y=_y, z=_z, timestamp=_timestamp; @end diff --git a/UIKit/Classes/UIAccelerometer.h b/UIKit/Classes/UIAccelerometer.h index 9a87ec6e..56e95afd 100644 --- a/UIKit/Classes/UIAccelerometer.h +++ b/UIKit/Classes/UIAccelerometer.h @@ -35,15 +35,9 @@ - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration; @end -@interface UIAccelerometer : NSObject { -@private - NSTimeInterval _updateInterval; - __unsafe_unretained id _delegate; -} - +@interface UIAccelerometer : NSObject + (UIAccelerometer *)sharedAccelerometer; @property (nonatomic, assign) id delegate; @property (nonatomic) NSTimeInterval updateInterval; - @end diff --git a/UIKit/Classes/UIAccelerometer.m b/UIKit/Classes/UIAccelerometer.m index 102bab98..86439642 100644 --- a/UIKit/Classes/UIAccelerometer.m +++ b/UIKit/Classes/UIAccelerometer.m @@ -30,7 +30,6 @@ #import "UIAccelerometer.h" @implementation UIAccelerometer -@synthesize updateInterval=_updateInterval, delegate=_delegate; + (UIAccelerometer *)sharedAccelerometer { diff --git a/UIKit/Classes/UIAccessibility.h b/UIKit/Classes/UIAccessibility.h index a0aadcbf..704d0efe 100644 --- a/UIKit/Classes/UIAccessibility.h +++ b/UIKit/Classes/UIAccessibility.h @@ -78,3 +78,14 @@ extern UIAccessibilityNotifications UIAccessibilityPageScrolledNotification; extern void UIAccessibilityPostNotification(UIAccessibilityNotifications notification, id argument); extern BOOL UIAccessibilityIsVoiceOverRunning(void); + +extern NSString *const UIAccessibilityVoiceOverStatusChanged; + +typedef NS_ENUM(NSInteger, UIAccessibilityScrollDirection) { + UIAccessibilityScrollDirectionRight = 1, + UIAccessibilityScrollDirectionLeft, + UIAccessibilityScrollDirectionUp, + UIAccessibilityScrollDirectionDown, + UIAccessibilityScrollDirectionNext, + UIAccessibilityScrollDirectionPrevious +}; diff --git a/UIKit/Classes/UIAccessibility.m b/UIKit/Classes/UIAccessibility.m index 4cff6f6f..a09468a8 100644 --- a/UIKit/Classes/UIAccessibility.m +++ b/UIKit/Classes/UIAccessibility.m @@ -48,6 +48,7 @@ UIAccessibilityNotifications UIAccessibilityAnnouncementNotification = 1002; UIAccessibilityNotifications UIAccessibilityPageScrolledNotification = 1003; +NSString *const UIAccessibilityVoiceOverStatusChanged = @"UIAccessibilityVoiceOverStatusChanged"; @implementation NSObject (UIAccessibility) - (BOOL)isAccessibilityElement diff --git a/UIKit/Classes/UIAccessibilityElement.h b/UIKit/Classes/UIAccessibilityElement.h index 333b8024..9994fdbe 100644 --- a/UIKit/Classes/UIAccessibilityElement.h +++ b/UIKit/Classes/UIAccessibilityElement.h @@ -29,20 +29,12 @@ #import "UIAccessibility.h" -@interface UIAccessibilityElement : NSObject { - NSString *_accessibilityLabel; - NSString *_accessibilityHint; - NSString *_accessibilityValue; - CGRect _accessibilityFrame; - UIAccessibilityTraits _accessibilityTraits; -} - +@interface UIAccessibilityElement : NSObject - (id)initWithAccessibilityContainer:(id)container; -@property (nonatomic, retain) NSString *accessibilityLabel; -@property (nonatomic, retain) NSString *accessibilityHint; -@property (nonatomic, retain) NSString *accessibilityValue; +@property (nonatomic, strong) NSString *accessibilityLabel; +@property (nonatomic, strong) NSString *accessibilityHint; +@property (nonatomic, strong) NSString *accessibilityValue; @property (nonatomic, assign) CGRect accessibilityFrame; @property (nonatomic, assign) UIAccessibilityTraits accessibilityTraits; - @end diff --git a/UIKit/Classes/UIAccessibilityElement.m b/UIKit/Classes/UIAccessibilityElement.m index a6cb4664..d33acbde 100644 --- a/UIKit/Classes/UIAccessibilityElement.m +++ b/UIKit/Classes/UIAccessibilityElement.m @@ -30,8 +30,6 @@ #import "UIAccessibilityElement.h" @implementation UIAccessibilityElement -@synthesize accessibilityLabel=_accessibilityLabel, accessibilityHint=_accessibilityHint, accessibilityValue=_accessibilityValue; -@synthesize accessibilityFrame=_accessibilityFrame, accessibilityTraits=_accessibilityTraits; - (id)initWithAccessibilityContainer:(id)container { @@ -40,12 +38,5 @@ - (id)initWithAccessibilityContainer:(id)container return self; } -- (void)dealloc -{ - [_accessibilityLabel release]; - [_accessibilityHint release]; - [_accessibilityValue release]; - [super dealloc]; -} @end diff --git a/UIKit/Classes/UIAction.h b/UIKit/Classes/UIAction.h index b64cc547..b5ef9f16 100644 --- a/UIKit/Classes/UIAction.h +++ b/UIKit/Classes/UIAction.h @@ -29,12 +29,7 @@ #import -@interface UIAction : NSObject { - __unsafe_unretained id _target; - SEL _action; -} - -@property (nonatomic, assign) id target; +@interface UIAction : NSObject +@property (nonatomic, weak) id target; @property (nonatomic, assign) SEL action; - @end diff --git a/UIKit/Classes/UIAction.m b/UIKit/Classes/UIAction.m index 5378ff5d..c05e825d 100644 --- a/UIKit/Classes/UIAction.m +++ b/UIKit/Classes/UIAction.m @@ -30,13 +30,12 @@ #import "UIAction.h" @implementation UIAction -@synthesize target=_target, action=_action; - (BOOL)isEqual:(id)object { if (object == self) { return YES; - } else if ([object isKindOfClass:[isa class]]) { + } else if ([object isKindOfClass:[[self class] class]]) { return ([object target] == self.target && [object action] == self.action); } else { return NO; diff --git a/UIKit/Classes/UIActionSheet.h b/UIKit/Classes/UIActionSheet.h index 1bc1fa8c..3c750aac 100644 --- a/UIKit/Classes/UIActionSheet.h +++ b/UIKit/Classes/UIActionSheet.h @@ -42,35 +42,14 @@ - (void)actionSheetCancel:(UIActionSheet *)actionSheet; @end -typedef enum { +typedef NS_ENUM(NSInteger, UIActionSheetStyle) { UIActionSheetStyleAutomatic = -1, UIActionSheetStyleDefault = UIBarStyleDefault, UIActionSheetStyleBlackTranslucent = UIBarStyleBlackTranslucent, UIActionSheetStyleBlackOpaque = UIBarStyleBlackOpaque, -} UIActionSheetStyle; - -@interface UIActionSheet : UIView { -@private - __unsafe_unretained id _delegate; - NSInteger _destructiveButtonIndex; - NSInteger _cancelButtonIndex; - NSInteger _firstOtherButtonIndex; - NSString *_title; - NSMutableArray *_menuTitles; - NSMutableArray *_separatorIndexes; - UIActionSheetStyle _actionSheetStyle; - id _menu; - - struct { - unsigned clickedButtonAtIndex : 1; - unsigned willPresentActionSheet : 1; - unsigned didPresentActionSheet : 1; - unsigned willDismissWithButtonIndex : 1; - unsigned didDismissWithButtonIndex : 1; - unsigned actionSheetCancel : 1; - } _delegateHas; -} +}; +@interface UIActionSheet : UIView - (id)initWithTitle:(NSString *)title delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...; - (NSInteger)addButtonWithTitle:(NSString *)title; @@ -91,5 +70,4 @@ typedef enum { @property (nonatomic) NSInteger cancelButtonIndex; @property (nonatomic, readonly) NSInteger firstOtherButtonIndex; @property (nonatomic, readonly) NSInteger numberOfButtons; - @end diff --git a/UIKit/Classes/UIActionSheet.m b/UIKit/Classes/UIActionSheet.m index af3e97a9..d207b235 100644 --- a/UIKit/Classes/UIActionSheet.m +++ b/UIKit/Classes/UIActionSheet.m @@ -31,15 +31,26 @@ #import "UIWindow.h" #import "UIScreenAppKitIntegration.h" #import "UIKitView.h" -#import "UIApplication+UIPrivate.h" +#import "UIApplicationAppKitIntegration.h" #import "UIBarButtonItem.h" #import #import #import -@implementation UIActionSheet -@synthesize delegate=_delegate, destructiveButtonIndex=_destructiveButtonIndex, cancelButtonIndex=_cancelButtonIndex, title=_title; -@synthesize firstOtherButtonIndex=_firstOtherButtonIndex, actionSheetStyle = _actionSheetStyle; +@implementation UIActionSheet { + NSMutableArray *_menuTitles; + NSMutableArray *_separatorIndexes; + NSMenu *_menu; + + struct { + unsigned clickedButtonAtIndex : 1; + unsigned willPresentActionSheet : 1; + unsigned didPresentActionSheet : 1; + unsigned willDismissWithButtonIndex : 1; + unsigned didDismissWithButtonIndex : 1; + unsigned actionSheetCancel : 1; + } _delegateHas; +} - (id)initWithFrame:(CGRect)frame { @@ -67,7 +78,7 @@ - (id)initWithTitle:(NSString *)title delegate:(id < UIActionSheetDelegate >)del va_list argumentList; va_start(argumentList, otherButtonTitles); - while ((buttonTitle=(__bridge NSString *)va_arg(argumentList, void *))) { + while ((buttonTitle=va_arg(argumentList, NSString *))) { [self addButtonWithTitle:buttonTitle]; } @@ -85,14 +96,6 @@ - (id)initWithTitle:(NSString *)title delegate:(id < UIActionSheetDelegate >)del return self; } -- (void)dealloc -{ - [_title release]; - [_menu release]; - [_menuTitles release]; - [_separatorIndexes release]; - [super dealloc]; -} - (void)setDelegate:(id)newDelegate { @@ -180,7 +183,6 @@ - (void)_showFromPoint:(CGPoint)point rightAligned:(BOOL)rightAligned inView:(UI [theItem setTag:index]; [theItem setTarget:self]; [_menu addItem:theItem]; - [theItem release]; } } @@ -242,13 +244,13 @@ - (void)_actuallyPresentTheMenuFromPoint:(NSValue *)aPoint } // this goes modal... meh. - BOOL itemSelected = [_menu popUpMenuPositioningItem:nil atLocation:NSPointFromCGPoint([aPoint CGPointValue]) inView:[self.window.screen UIKitView]]; + BOOL itemSelected = [_menu popUpMenuPositioningItem:nil atLocation:NSPointFromCGPoint([aPoint CGPointValue]) inView:self.window.screen.UIKitView]; // because of the modal nature of NSMenu, if there's a touch active (like, being held down) when a menu is triggered, the modal NSMenu // takes over the event stream and so a mouseUp is never delivered to the UIKitView. This means it never gets to the app and it leaves // the "touch" tracking system in an inconsistent state. This triggers the touchesCancelled UIResponder stuff to allow UIKit code to clean // itself up after the menu is done. - [[UIApplication sharedApplication] _cancelTouches]; + UIApplicationInterruptTouchesInView(nil); if (!itemSelected) { [self _clickedButtonAtIndex:_cancelButtonIndex]; @@ -302,7 +304,6 @@ - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)anim } // kill off the menu - [_menu release]; _menu = nil; // remove ourself from the superview that we piggy-backed on diff --git a/UIKit/Classes/UIActivityIndicatorView.h b/UIKit/Classes/UIActivityIndicatorView.h index 71fe74b5..d3764b1e 100644 --- a/UIKit/Classes/UIActivityIndicatorView.h +++ b/UIKit/Classes/UIActivityIndicatorView.h @@ -29,19 +29,13 @@ #import "UIView.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIActivityIndicatorViewStyle) { UIActivityIndicatorViewStyleWhiteLarge, UIActivityIndicatorViewStyleWhite, UIActivityIndicatorViewStyleGray, -} UIActivityIndicatorViewStyle; - -@interface UIActivityIndicatorView : UIView { -@private - UIActivityIndicatorViewStyle _activityIndicatorViewStyle; - BOOL _hidesWhenStopped; - BOOL _animating; -} +}; +@interface UIActivityIndicatorView : UIView - (id)initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style; - (void)startAnimating; - (void)stopAnimating; @@ -49,5 +43,5 @@ typedef enum { @property BOOL hidesWhenStopped; @property UIActivityIndicatorViewStyle activityIndicatorViewStyle; - +@property (readwrite, nonatomic, retain) UIColor *color; @end diff --git a/UIKit/Classes/UIActivityIndicatorView.m b/UIKit/Classes/UIActivityIndicatorView.m index af715172..503ab0f4 100644 --- a/UIKit/Classes/UIActivityIndicatorView.m +++ b/UIKit/Classes/UIActivityIndicatorView.m @@ -45,7 +45,7 @@ static CGSize UIActivityIndicatorViewStyleSize(UIActivityIndicatorViewStyle styl } } -static UIImage *UIActivityIndicatorViewFrameImage(UIActivityIndicatorViewStyle style, NSInteger frame, NSInteger numberOfFrames, CGFloat scale) +static UIImage *UIActivityIndicatorViewFrameImage(UIActivityIndicatorViewStyle style, UIColor *toothColor, NSInteger frame, NSInteger numberOfFrames, CGFloat scale) { const CGSize frameSize = UIActivityIndicatorViewStyleSize(style); const CGFloat radius = frameSize.width / 2.f; @@ -53,7 +53,9 @@ static CGSize UIActivityIndicatorViewStyleSize(UIActivityIndicatorViewStyle styl const CGFloat numberOfTeeth = 12; const CGFloat toothWidth = (style == UIActivityIndicatorViewStyleWhiteLarge)? 3.5 : 2; - UIColor *toothColor = (style == UIActivityIndicatorViewStyleGray)? [UIColor grayColor] : [UIColor whiteColor]; + if (!toothColor) { + toothColor = (style == UIActivityIndicatorViewStyleGray)? [UIColor grayColor] : [UIColor whiteColor]; + } UIGraphicsBeginImageContextWithOptions(frameSize, NO, scale); CGContextRef c = UIGraphicsGetCurrentContext(); @@ -82,7 +84,11 @@ static CGSize UIActivityIndicatorViewStyleSize(UIActivityIndicatorViewStyle styl return frameImage; } -@implementation UIActivityIndicatorView +@implementation UIActivityIndicatorView { + BOOL _animating; + UIActivityIndicatorViewStyle _activityIndicatorViewStyle; + BOOL _hidesWhenStopped; +} - (id)initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style { @@ -94,6 +100,7 @@ - (id)initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style self.activityIndicatorViewStyle = style; self.hidesWhenStopped = YES; self.opaque = NO; + self.contentMode = UIViewContentModeCenter; } return self; @@ -110,13 +117,7 @@ - (id)initWithFrame:(CGRect)frame - (CGSize)sizeThatFits:(CGSize)aSize { - UIActivityIndicatorViewStyle style; - - @synchronized (self) { - style = _activityIndicatorViewStyle; - } - - return UIActivityIndicatorViewStyleSize(style); + return UIActivityIndicatorViewStyleSize(self.activityIndicatorViewStyle); } - (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)style @@ -135,13 +136,9 @@ - (void)setActivityIndicatorViewStyle:(UIActivityIndicatorViewStyle)style - (UIActivityIndicatorViewStyle)activityIndicatorViewStyle { - UIActivityIndicatorViewStyle style; - @synchronized (self) { - style = _activityIndicatorViewStyle; + return _activityIndicatorViewStyle; } - - return style; } - (void)setHidesWhenStopped:(BOOL)hides @@ -159,45 +156,45 @@ - (void)setHidesWhenStopped:(BOOL)hides - (BOOL)hidesWhenStopped { - BOOL hides; - @synchronized (self) { - hides = _hidesWhenStopped; + return _hidesWhenStopped; } - - return hides; } - (void)_startAnimation { - const NSInteger numberOfFrames = 12; - const CFTimeInterval animationDuration = 0.8; - - NSMutableArray *images = [[NSMutableArray alloc] initWithCapacity:numberOfFrames]; - - for (NSInteger frameNumber=0; frameNumber _delegate; - NSInteger _cancelButtonIndex; - NSMutableArray *_buttonTitles; - - struct { - unsigned clickedButtonAtIndex : 1; - unsigned alertViewCancel : 1; - unsigned willPresentAlertView : 1; - unsigned didPresentAlertView : 1; - unsigned willDismissWithButtonIndex : 1; - unsigned didDismissWithButtonIndex : 1; - } _delegateHas; -} - +@interface UIAlertView : UIView - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...; - - (NSInteger)addButtonWithTitle:(NSString *)title; - (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex; - (void)show; @@ -61,7 +43,6 @@ @property (nonatomic, assign) id delegate; @property (nonatomic) NSInteger cancelButtonIndex; @property (nonatomic,readonly) NSInteger numberOfButtons; - @end @protocol UIAlertViewDelegate diff --git a/UIKit/Classes/UIAlertView.m b/UIKit/Classes/UIAlertView.m index 94fee20f..9e004774 100644 --- a/UIKit/Classes/UIAlertView.m +++ b/UIKit/Classes/UIAlertView.m @@ -34,12 +34,18 @@ #import #import -@interface UIAlertView () -@property (nonatomic, retain) NSMutableArray *buttonTitles; -@end - -@implementation UIAlertView -@synthesize title=_title, message=_message, delegate=_delegate, cancelButtonIndex=_cancelButtonIndex, buttonTitles=_buttonTitles; +@implementation UIAlertView { + NSMutableArray *_buttonTitles; + + struct { + unsigned clickedButtonAtIndex : 1; + unsigned alertViewCancel : 1; + unsigned willPresentAlertView : 1; + unsigned didPresentAlertView : 1; + unsigned willDismissWithButtonIndex : 1; + unsigned didDismissWithButtonIndex : 1; + } _delegateHas; +} - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... { @@ -47,7 +53,7 @@ - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)d self.title = title; self.message = message; self.delegate = delegate; - self.buttonTitles = [NSMutableArray arrayWithCapacity:1]; + _buttonTitles = [NSMutableArray arrayWithCapacity:1]; if (cancelButtonTitle) { self.cancelButtonIndex = [self addButtonWithTitle:cancelButtonTitle]; @@ -60,7 +66,7 @@ - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)d va_list argumentList; va_start(argumentList, otherButtonTitles); - while ((buttonTitle=(__bridge NSString *)va_arg(argumentList, void *))) { + while ((buttonTitle=va_arg(argumentList, NSString *))) { [self addButtonWithTitle:buttonTitle]; } @@ -70,13 +76,6 @@ - (id)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)d return self; } -- (void)dealloc -{ - [_title release]; - [_message release]; - [_buttonTitles release]; - [super dealloc]; -} - (void)setDelegate:(id)newDelegate { @@ -91,19 +90,19 @@ - (void)setDelegate:(id)newDelegate - (NSInteger)addButtonWithTitle:(NSString *)title { - [self.buttonTitles addObject:title]; - return ([self.buttonTitles count] - 1); + [_buttonTitles addObject:title]; + return ([_buttonTitles count] - 1); } - (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex { - return [self.buttonTitles objectAtIndex:buttonIndex]; + return [_buttonTitles objectAtIndex:buttonIndex]; } - (NSInteger)numberOfButtons { - return [self.buttonTitles count]; + return [_buttonTitles count]; } - (void)show @@ -115,8 +114,8 @@ - (void)show // NSAlert does have a mode that doesn't block the runloop, but it has other drawbacks that I didn't like // so opting to do it this way here. :/ - NSAlert *alert = [[[NSAlert alloc] init] autorelease]; - NSMutableArray *buttonOrder = [[[NSMutableArray alloc] initWithCapacity:self.numberOfButtons] autorelease]; + NSAlert *alert = [[NSAlert alloc] init]; + NSMutableArray *buttonOrder = [[NSMutableArray alloc] initWithCapacity:self.numberOfButtons]; if (self.title) { [alert setMessageText:self.title]; @@ -128,13 +127,13 @@ - (void)show for (NSInteger buttonIndex=0; buttonIndex= 0) { - NSButton *btn = [alert addButtonWithTitle:[self.buttonTitles objectAtIndex:self.cancelButtonIndex]]; + NSButton *btn = [alert addButtonWithTitle:[_buttonTitles objectAtIndex:self.cancelButtonIndex]]; // only change the key equivelent if there's more than one button, otherwise we lose the "Return" key for triggering the default action if (self.numberOfButtons > 1) { diff --git a/UIKit/Classes/UIAppearanceInstance.h b/UIKit/Classes/UIAppearanceInstance.h index 05a5cc26..f60166f3 100644 --- a/UIKit/Classes/UIAppearanceInstance.h +++ b/UIKit/Classes/UIAppearanceInstance.h @@ -35,8 +35,8 @@ + (id)appearance; + (id)appearanceWhenContainedIn:(Class )containerClass, ...; -- (void)_appearancePropertyDidChange:(UIAppearanceProperty *)property; -- (id)_appearanceContainer; -- (void)_updateAppearanceIfNeeded; -- (void)_setAppearanceNeedsUpdate; +- (id)_UIAppearanceContainer; +- (void)_UIAppearancePropertyDidChange:(id)property; +- (void)_UIAppearanceUpdateIfNeeded; +- (void)_UIAppearanceSetNeedsUpdate; @end diff --git a/UIKit/Classes/UIAppearanceInstance.m b/UIKit/Classes/UIAppearanceInstance.m index 5583b3c3..9a9474c7 100644 --- a/UIKit/Classes/UIAppearanceInstance.m +++ b/UIKit/Classes/UIAppearanceInstance.m @@ -33,56 +33,8 @@ #import static const char *UIAppearanceClassAssociatedObjectKey = "UIAppearanceClassAssociatedObjectKey"; -static const char *UIAppearanceInstanceAssociatedObjectKey = "UIAppearanceInstanceAssociatedObjectKey"; - -static NSString * const UIAppearanceInstancePropertiesKey = @"UIAppearanceInstancePropertiesKey"; -static NSString * const UIAppearanceInstanceNeedsUpdateKey = @"UIAppearanceInstanceNeedsUpdateKey"; - -static NSMutableDictionary *UIAppearanceInstanceDictionary(id object) -{ - return objc_getAssociatedObject(object, UIAppearanceInstanceAssociatedObjectKey); -} - -static NSMutableDictionary *UIAppearanceInstanceDictionaryCreateIfNeeded(id object) -{ - NSMutableDictionary *info = UIAppearanceInstanceDictionary(object); - - if (!info) { - info = [NSMutableDictionary dictionaryWithCapacity:1]; - objc_setAssociatedObject(object, UIAppearanceInstanceAssociatedObjectKey, info, OBJC_ASSOCIATION_RETAIN); - } - - return info; -} - -static void UIAppearanceInstanceSetProperties(id object, NSSet *properties) -{ - if ([properties count] > 0) { - [UIAppearanceInstanceDictionaryCreateIfNeeded(object) setObject:properties forKey:UIAppearanceInstancePropertiesKey]; - } else { - [UIAppearanceInstanceDictionary(object) removeObjectForKey:UIAppearanceInstancePropertiesKey]; - } -} - -static NSSet *UIAppearanceInstanceProperties(id object) -{ - return [UIAppearanceInstanceDictionary(object) objectForKey:UIAppearanceInstancePropertiesKey]; -} - -static void UIAppearanceInstancePropertyDidChange(id object, UIAppearanceProperty *property) -{ - UIAppearanceInstanceSetProperties(object, [[NSSet setWithObject:property] setByAddingObjectsFromSet:UIAppearanceInstanceProperties(object)]); -} - -static BOOL UIAppearanceInstanceNeedsUpdate(id object) -{ - return [[UIAppearanceInstanceDictionary(object) objectForKey:UIAppearanceInstanceNeedsUpdateKey] boolValue]; -} - -static void UIAppearanceInstanceSetNeedsUpdate(id object, BOOL needsUpdate) -{ - [UIAppearanceInstanceDictionaryCreateIfNeeded(object) setObject:[NSNumber numberWithBool:needsUpdate] forKey:UIAppearanceInstanceNeedsUpdateKey]; -} +static const char *UIAppearanceChangedPropertiesKey = "UIAppearanceChangedPropertiesKey"; +static const char *UIAppearancePropertiesAreUpToDateKey = "UIAppearancePropertiesAreUpToDateKey"; static NSArray *UIAppearanceHierarchyForClass(Class klass) { @@ -93,7 +45,7 @@ static void UIAppearanceInstanceSetNeedsUpdate(id object, BOOL needsUpdate) klass = [klass superclass]; } - return [classes autorelease]; + return classes; } @implementation NSObject (UIAppearanceInstance) @@ -124,107 +76,114 @@ + (id)appearanceWhenContainedIn:(Class )containerClass, . UIAppearanceProxy *record = [appearanceRules objectForKey:containmentPath]; if (!record) { - record = [[[UIAppearanceProxy alloc] initWithClass:self] autorelease]; + record = [[UIAppearanceProxy alloc] initWithClass:self]; [appearanceRules setObject:record forKey:containmentPath]; } return record; } -- (void)_appearancePropertyDidChange:(UIAppearanceProperty *)property -{ - UIAppearanceInstancePropertyDidChange(self, property); -} - -- (id)_appearanceContainer +- (id)_UIAppearanceContainer { return nil; } -- (void)_updateAppearanceIfNeeded +- (void)_UIAppearanceUpdateIfNeeded { - if (UIAppearanceInstanceNeedsUpdate(self)) { - // first go down our own class heirarchy until we find the root of the UIAppearance protocol - // then we'll start at the bottom and work up while checking each class for all relevant rules - // that apply to this instance at this time. - - NSArray *classes = UIAppearanceHierarchyForClass([self class]); - NSMutableDictionary *propertiesToSet = [NSMutableDictionary dictionaryWithCapacity:0]; + // check if we are already up to date, if so, return early + if (objc_getAssociatedObject(self, UIAppearancePropertiesAreUpToDateKey)) { + return; + } + + // first go down our own class heirarchy until we find the root of the UIAppearance protocol + // then we'll start at the bottom and work up while checking each class for all relevant rules + // that apply to this instance at this time. + + NSArray *classes = UIAppearanceHierarchyForClass([self class]); + NSMutableDictionary *propertiesToSet = [NSMutableDictionary dictionaryWithCapacity:0]; + + for (Class klass in classes) { + NSMutableDictionary *rules = objc_getAssociatedObject(klass, UIAppearanceClassAssociatedObjectKey); - for (Class klass in classes) { - NSMutableDictionary *rules = objc_getAssociatedObject(klass, UIAppearanceClassAssociatedObjectKey); - - // sorts the rule keys (which are arrays of classes) by length - // if the lengths match, it sorts based on the last class being a superclass of the other or vice-versa - // if the last classes aren't related at all, it marks them equal (I suspect these cases will always be filtered out in the next step) - NSArray *sortedRulePaths = [[rules allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSArray *path1, NSArray *path2) { - if ([path1 count] == [path2 count]) { - if ([[path2 lastObject] isKindOfClass:[path1 lastObject]]) { - return (NSComparisonResult)NSOrderedAscending; - } else if ([[path1 lastObject] isKindOfClass:[path2 lastObject]]) { - return (NSComparisonResult)NSOrderedDescending; - } else { - return (NSComparisonResult)NSOrderedSame; - } - } else if ([path1 count] < [path2 count]) { + // sorts the rule keys (which are arrays of classes) by length + // if the lengths match, it sorts based on the last class being a superclass of the other or vice-versa + // if the last classes aren't related at all, it marks them equal (I suspect these cases will always be filtered out in the next step) + NSArray *sortedRulePaths = [[rules allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSArray *path1, NSArray *path2) { + if ([path1 count] == [path2 count]) { + if ([[path2 lastObject] isKindOfClass:[path1 lastObject]]) { return (NSComparisonResult)NSOrderedAscending; - } else { + } else if ([[path1 lastObject] isKindOfClass:[path2 lastObject]]) { return (NSComparisonResult)NSOrderedDescending; + } else { + return (NSComparisonResult)NSOrderedSame; } - }]; + } else if ([path1 count] < [path2 count]) { + return (NSComparisonResult)NSOrderedAscending; + } else { + return (NSComparisonResult)NSOrderedDescending; + } + }]; + + // we should now have a list of classes to check for rule settings for this instance, so now we spin + // through those and fetch the properties and values and add them to the dictionary of things to do. + // before applying a rule's properties, we must make sure this instance is qualified, so we must check + // this instance's container hierarchy against ever class that makes up the rule. + for (NSArray *rule in sortedRulePaths) { + BOOL shouldApplyRule = YES; - // we should now have a list of classes to check for rule settings for this instance, so now we spin - // through those and fetch the properties and values and add them to the dictionary of things to do. - // before applying a rule's properties, we must make sure this instance is qualified, so we must check - // this instance's container hierarchy against ever class that makes up the rule. - for (NSArray *rule in sortedRulePaths) { - BOOL shouldApplyRule = YES; - - for (Class klass in [rule reverseObjectEnumerator]) { - id container = [self _appearanceContainer]; + for (Class klass in [rule reverseObjectEnumerator]) { + id container = [self _UIAppearanceContainer]; - while (container && ![container isKindOfClass:klass]) { - container = [container _appearanceContainer]; - } - - if (!container) { - shouldApplyRule = NO; - break; - } + while (container && ![container isKindOfClass:klass]) { + container = [container _UIAppearanceContainer]; } - if (shouldApplyRule) { - UIAppearanceProxy *proxy = [rules objectForKey:rule]; - [propertiesToSet addEntriesFromDictionary:[proxy _appearancePropertiesAndValues]]; + if (!container) { + shouldApplyRule = NO; + break; } } + + if (shouldApplyRule) { + UIAppearanceProxy *proxy = [rules objectForKey:rule]; + [propertiesToSet addEntriesFromDictionary:[proxy _appearancePropertiesAndValues]]; + } } - - // before setting the actual properties on the instance, save off a copy of the existing modified properties - // because the act of setting the UIAppearance properties will end up messing with that set. - // after we're done actually applying everything, reset the modified properties set to what it was before. - NSSet *originalProperties = [UIAppearanceInstanceProperties(self) copy]; - - // subtract any properties that have been overriden from the list to apply - [propertiesToSet removeObjectsForKeys:[originalProperties allObjects]]; - - // now apply everything that's left - [propertiesToSet enumerateKeysAndObjectsUsingBlock:^(UIAppearanceProperty *property, NSValue *value, BOOL *stop) { - [property invokeSetterUsingTarget:self withValue:value]; - }]; - - // now reset our set of changes properties to the original set so we don't count the UIAppearance defaults - UIAppearanceInstanceSetProperties(self, originalProperties); - [originalProperties release]; - - // done! - UIAppearanceInstanceSetNeedsUpdate(self, NO); } + + // before setting the actual properties on the instance, save off a copy of the existing modified properties + // because the act of setting the UIAppearance properties will end up messing with that set. + // after we're done actually applying everything, reset the modified properties set to what it was before. + NSSet *originalProperties = objc_getAssociatedObject(self, UIAppearanceChangedPropertiesKey); + + // subtract any properties that have been overriden from the list to apply + [propertiesToSet removeObjectsForKeys:[originalProperties allObjects]]; + + // now apply everything that's left + for (UIAppearanceProperty *property in [propertiesToSet allValues]) { + [property invokeUsingTarget:self]; + } + + // now reset our set of changes properties to the original set so we don't count the UIAppearance defaults as overrides + objc_setAssociatedObject(self, UIAppearanceChangedPropertiesKey, originalProperties, OBJC_ASSOCIATION_RETAIN); + + // done! + objc_setAssociatedObject(self, UIAppearancePropertiesAreUpToDateKey, @(1), OBJC_ASSOCIATION_RETAIN); } -- (void)_setAppearanceNeedsUpdate +- (void)_UIAppearanceSetNeedsUpdate { - UIAppearanceInstanceSetNeedsUpdate(self, YES); + // this removes UIAppearancePropertiesAreUpToDateKey which will trigger _UIAppearanceUpdateIfNeeded to run (if it is called later) + objc_setAssociatedObject(self, UIAppearancePropertiesAreUpToDateKey, nil, OBJC_ASSOCIATION_RETAIN); +} + +- (void)_UIAppearancePropertyDidChange:(id)property +{ + // note an overridden property value so we don't override it with a default value in -_UIAppearanceUpdateIfNeeded + // this occurs when a value is set directly using a setter on an instance (such as "label.textColor = myColor;") + + NSSet *changedProperties = [NSSet setWithSet:objc_getAssociatedObject(self, UIAppearanceChangedPropertiesKey)]; + objc_setAssociatedObject(self, UIAppearanceChangedPropertiesKey, [changedProperties setByAddingObject:property], OBJC_ASSOCIATION_RETAIN); } @end diff --git a/UIKit/Classes/UIAppearanceProperty.h b/UIKit/Classes/UIAppearanceProperty.h index d9e1ff66..20451623 100644 --- a/UIKit/Classes/UIAppearanceProperty.h +++ b/UIKit/Classes/UIAppearanceProperty.h @@ -27,16 +27,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import - -@interface UIAppearanceProperty : NSObject { - SEL cmd; - NSArray *axisValues; -} - -- (id)initWithSelector:(SEL)sel axisValues:(NSArray *)values; -- (void)invokeSetterUsingTarget:(id)target withValue:(NSValue *)value; - -@property (nonatomic, readonly) NSArray *axisValues; +#import "UIAppearanceProxy.h" +@interface UIAppearanceProperty : NSObject +- (id)initWithInvocation:(NSInvocation *)setterInvocation; +- (void)invokeUsingTarget:(id)target; +- (void)setReturnValueForInvocation:(NSInvocation *)getterInvocation; @end diff --git a/UIKit/Classes/UIAppearanceProperty.m b/UIKit/Classes/UIAppearanceProperty.m index 2b8f3143..c08f368e 100644 --- a/UIKit/Classes/UIAppearanceProperty.m +++ b/UIKit/Classes/UIAppearanceProperty.m @@ -29,69 +29,59 @@ #import "UIAppearanceProperty.h" -@implementation UIAppearanceProperty -@synthesize axisValues; +@implementation UIAppearanceProperty { + NSInvocation *_invocation; +} -- (id)initWithSelector:(SEL)sel axisValues:(NSArray *)values +- (id)initWithInvocation:(NSInvocation *)setterInvocation { if ((self=[super init])) { - cmd = sel; - axisValues = [values copy]; + NSMethodSignature *methodSignature = [setterInvocation methodSignature]; + _invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + + // we want to copy every argument except for target (which is argument 0) + // so start at 1 and copy... + for (int i = 1; i < [methodSignature numberOfArguments]; i++) { + const char *valueType = [methodSignature getArgumentTypeAtIndex:i]; + NSUInteger bufferSize = 0; + NSGetSizeAndAlignment(valueType, &bufferSize, NULL); + UInt8 valueBuffer[bufferSize]; + memset(valueBuffer, 0, bufferSize); + + [setterInvocation getArgument:valueBuffer atIndex:i]; + [_invocation setArgument:valueBuffer atIndex:i]; + } + + // this is very important since we're caching this invocation! + [_invocation retainArguments]; } return self; } -- (void)dealloc -{ - [axisValues release]; - [super dealloc]; -} - -- (BOOL)isEqual:(id)object +- (void)invokeUsingTarget:(id)target { - if (object == self) { - return YES; - } else if ([object isKindOfClass:[UIAppearanceProperty class]]) { - UIAppearanceProperty *entry = (UIAppearanceProperty *)object; - return cmd == entry->cmd && [axisValues isEqual:entry->axisValues]; - } else { - return NO; - } + [_invocation invokeWithTarget:target]; } -- (NSUInteger)hash +- (void)setReturnValueForInvocation:(NSInvocation *)getterInvocation { - return [NSStringFromSelector(cmd) hash] ^ [axisValues hash]; -} - -- (id)copyWithZone:(NSZone *)zone -{ - return [[UIAppearanceProperty alloc] initWithSelector:cmd axisValues:axisValues]; -} + NSMethodSignature *methodSignature = [_invocation methodSignature]; + + // ensure we have a value to return (which is expected to be at argument index 2) + NSAssert([methodSignature numberOfArguments] >= 2, @"stored invocation has no property value"); -- (void)invokeSetterUsingTarget:(id)target withValue:(NSValue *)value -{ - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:cmd]]; + // fetch and return the property value from our stored invocation + const char *valueType = [methodSignature getArgumentTypeAtIndex:2]; + NSUInteger bufferSize = 0; + NSGetSizeAndAlignment(valueType, &bufferSize, NULL); + UInt8 valueBuffer[bufferSize]; + memset(valueBuffer, 0, bufferSize); + [_invocation getArgument:valueBuffer atIndex:2]; - for (int i=0; i<[[invocation methodSignature] numberOfArguments]; i++) { - if (i == 0) { - [invocation setTarget:target]; - } else if (i == 1) { - [invocation setSelector:cmd]; - } else { - NSValue *v = (i == 2)? value : [axisValues objectAtIndex:i-3]; - - NSUInteger bufferSize = 0; - NSGetSizeAndAlignment([v objCType], &bufferSize, NULL); - UInt8 argumentBuffer[bufferSize]; - memset(argumentBuffer, 0, bufferSize); - - [v getValue:argumentBuffer]; - [invocation setArgument:argumentBuffer atIndex:i]; - } - } + // ensure the property value type's size matches the expected return value's size + NSAssert(bufferSize == [[getterInvocation methodSignature] methodReturnLength], @"getter return length not equal to property value size"); - [invocation invoke]; + [getterInvocation setReturnValue:valueBuffer]; } @end diff --git a/UIKit/Classes/UIAppearanceProxy.h b/UIKit/Classes/UIAppearanceProxy.h index 8161109d..93c837c2 100644 --- a/UIKit/Classes/UIAppearanceProxy.h +++ b/UIKit/Classes/UIAppearanceProxy.h @@ -30,12 +30,7 @@ #import "UIAppearance.h" #import -@interface UIAppearanceProxy : NSObject { - Class _targetClass; - NSMutableDictionary *_settings; -} - +@interface UIAppearanceProxy : NSObject - (id)initWithClass:(Class)k; - (NSDictionary *)_appearancePropertiesAndValues; - @end diff --git a/UIKit/Classes/UIAppearanceProxy.m b/UIKit/Classes/UIAppearanceProxy.m index 2bbfc74f..251d6aba 100644 --- a/UIKit/Classes/UIAppearanceProxy.m +++ b/UIKit/Classes/UIAppearanceProxy.m @@ -134,20 +134,24 @@ static IMP GetOriginalMethodIMP(id self, SEL cmd) // is the reason we have to go through all this trouble overriding stuff in the first place! static void DidSetPropertyWithAxisValues(id self, SEL cmd, NSInteger numberOfAxisValues, NSInteger *axisValues) { - NSMutableArray *values = [NSMutableArray arrayWithCapacity:numberOfAxisValues]; + NSMutableArray *propertyKey = [NSMutableArray array]; + // IMPORTANT! Must build the property key the same way we do down in -forwardInvocation: for (NSInteger i=0; i= 0) { \ va_list args; va_start(args, property); \ @@ -212,7 +216,10 @@ static IMP ImplementationForPropertyType(const char *t) } } -@implementation UIAppearanceProxy +@implementation UIAppearanceProxy { + Class _targetClass; + NSMutableDictionary *_settings; +} - (id)initWithClass:(Class)k { @@ -223,12 +230,6 @@ - (id)initWithClass:(Class)k return self; } -- (void)dealloc -{ - [_settings release]; - [super dealloc]; -} - - (void)forwardInvocation:(NSInvocation *)anInvocation { // allowed selector formats: @@ -242,54 +243,75 @@ - (void)forwardInvocation:(NSInvocation *)anInvocation // each axis must be either NSInteger or NSUInteger. // throw an exception if other types are used in an axis. + NSMethodSignature *methodSignature = [anInvocation methodSignature]; + NSMutableArray *propertyKey = [NSMutableArray array]; + // see if this selector is a setter or a getter - const BOOL isSetter = [NSStringFromSelector([anInvocation selector]) hasPrefix:@"set"] && [[anInvocation methodSignature] numberOfArguments] > 2 && strcmp([[anInvocation methodSignature] methodReturnType], @encode(void)) == 0; - const BOOL isGetter = !isSetter && strcmp([[anInvocation methodSignature] methodReturnType], @encode(void)) != 0; + const BOOL isSetter = [NSStringFromSelector([anInvocation selector]) hasPrefix:@"set"] && [methodSignature numberOfArguments] > 2 && strcmp([methodSignature methodReturnType], @encode(void)) == 0; + const BOOL isGetter = !isSetter && strcmp([methodSignature methodReturnType], @encode(void)) != 0; // ensure that the property type is legit - const char *propertyType = isSetter? [[anInvocation methodSignature] getArgumentTypeAtIndex:2] : (isGetter? [[anInvocation methodSignature] methodReturnType] : NULL); + const char *propertyType = isSetter? [methodSignature getArgumentTypeAtIndex:2] : (isGetter? [methodSignature methodReturnType] : NULL); if (!TypeIsPropertyType(propertyType)) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"property type must be id, NSInteger, NSUInteger, CGFloat, CGPoint, CGSize, CGRect, UIEdgeInsets or UIOffset" userInfo:nil]; } - - // this will hold the NSValue objects made out of the arguments - NSMutableArray *argumentValues = [NSMutableArray arrayWithCapacity:[[anInvocation methodSignature] numberOfArguments]-2]; - - // box the arguments - for (int i=2; i<[[anInvocation methodSignature] numberOfArguments]; i++) { - const char *type = [[anInvocation methodSignature] getArgumentTypeAtIndex:i]; - - if ((isSetter && i > 2) || isGetter) { - // ensure that the axis arguments are integers - if (!TypeIsIntegerType(type)) { - @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"axis type must be NSInteger or NSUInteger" userInfo:nil]; - } + + // use axis arguments when building the unique key for this property + const int axisStartIndex = isSetter? 3 : 2; + for (int i=axisStartIndex; i<[methodSignature numberOfArguments]; i++) { + const char *type = [methodSignature getArgumentTypeAtIndex:i]; + + // ensure that the axis arguments are integers + if (!TypeIsIntegerType(type)) { + @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"axis type must be NSInteger or NSUInteger" userInfo:nil]; } - // we need a buffer to pull out the argument data, so we'll figure out the size of the data first and then make the buffer - NSUInteger bufferSize = 0; - NSGetSizeAndAlignment(type, &bufferSize, NULL); - UInt8 argumentBuffer[bufferSize]; - memset(argumentBuffer, 0, bufferSize); - - // fetch the actual value data into our fancy buffer - [anInvocation getArgument:argumentBuffer atIndex:i]; - - // now box it up and tie it with a bow - NSValue *value = [NSValue value:argumentBuffer withObjCType:type]; - - if (value) { - [argumentValues addObject:value]; + NSInteger axisValue = 0; + [anInvocation getArgument:&axisValue atIndex:i]; + [propertyKey addObject:@(axisValue)]; + } + + if (isGetter) { + // convert the getter's selector into a setter's selector since that's what we actually key the property value with + NSMutableString *selectorKeyString = [NSStringFromSelector([anInvocation selector]) mutableCopy]; + [selectorKeyString replaceCharactersInRange:NSMakeRange(0, 1) withString:[[selectorKeyString substringToIndex:1] uppercaseString]]; + [selectorKeyString insertString:@"set" atIndex:0]; + + // if the property has 1 or more axis parts, we need to take those into account, too + if ([methodSignature numberOfArguments] > 2) { + const NSRange colonRange = [selectorKeyString rangeOfString:@":"]; + const NSRange forRange = [selectorKeyString rangeOfString:@"For"]; + + if (colonRange.location != NSNotFound && forRange.location != NSNotFound && colonRange.location > NSMaxRange(forRange)) { + const NSRange axisNameRange = NSMakeRange(forRange.location+3, colonRange.location-forRange.location-3); + NSString *axisName = [selectorKeyString substringWithRange:axisNameRange]; + axisName = [axisName stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[axisName substringToIndex:1] uppercaseString]]; + NSString *axisSelectorPartName = [NSString stringWithFormat:@"for%@:", axisName]; + [selectorKeyString insertString:axisSelectorPartName atIndex:NSMaxRange(colonRange)]; + [selectorKeyString replaceCharactersInRange:NSMakeRange(forRange.location, colonRange.location-forRange.location) withString:@""]; + } } else { - @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"something terrible has happened" userInfo:nil]; + [selectorKeyString appendString:@":"]; } + + // finish building the property key now that we have the expected selector name + [propertyKey addObject:[selectorKeyString copy]]; + + // fetch the current property value using the key and put it in the current invocation + // so it can be returned to the caller + UIAppearanceProperty *propertyValue = [_settings objectForKey:propertyKey]; + [propertyValue setReturnValueForInvocation:anInvocation]; } + else if (isSetter) { + NSString *selectorString = NSStringFromSelector([anInvocation selector]); - if (isSetter) { - // make a key so we can store this particular property value given the axis values - UIAppearanceProperty *key = [[UIAppearanceProperty alloc] initWithSelector:[anInvocation selector] - axisValues:[argumentValues subarrayWithRange:NSMakeRange(1, [argumentValues count]-1)]]; - [_settings setObject:[argumentValues objectAtIndex:0] forKey:key]; + // finish building the property key using the selector we have + [propertyKey addObject:selectorString]; + + // save the actual property value using the key + [_settings setObject:[[UIAppearanceProperty alloc] initWithInvocation:anInvocation] forKey:propertyKey]; + + // WARNING! Swizzling ahead! // what we're doing here is sneakily overriding the existing implemention with our own so we can track when the setter is called // and not have the appearance defaults override if a more local setting has been made. @@ -302,9 +324,8 @@ - (void)forwardInvocation:(NSInvocation *)anInvocation // for that are either deprecated or marked as "don't use" in the docs. :/ this is the best I could come up with given my // current knowledge of how everything works at this abstraction level. abandon all hope, ye who enter here... - NSString *selectorString = NSStringFromSelector([anInvocation selector]); NSMutableDictionary *methodOverrides = objc_getAssociatedObject(_targetClass, UIAppearanceSetterOverridesAssociatedObjectKey); - + if (!methodOverrides) { methodOverrides = [NSMutableDictionary dictionaryWithCapacity:1]; objc_setAssociatedObject(_targetClass, UIAppearanceSetterOverridesAssociatedObjectKey, methodOverrides, OBJC_ASSOCIATION_RETAIN); @@ -315,7 +336,7 @@ - (void)forwardInvocation:(NSInvocation *)anInvocation if (method) { IMP implementation = method_getImplementation(method); - IMP overrideImplementation = ImplementationForPropertyType([[anInvocation methodSignature] getArgumentTypeAtIndex:2]); + IMP overrideImplementation = ImplementationForPropertyType([methodSignature getArgumentTypeAtIndex:2]); if (implementation != overrideImplementation) { [methodOverrides setObject:[NSValue valueWithBytes:&implementation objCType:@encode(IMP)] forKey:selectorString]; @@ -323,47 +344,8 @@ - (void)forwardInvocation:(NSInvocation *)anInvocation } } } - - [key release]; - } else if (isGetter) { - // convert the getter's selector into a setter's selector since that's what we keyed on above - NSMutableString *selectorString = [NSStringFromSelector([anInvocation selector]) mutableCopy]; - [selectorString replaceCharactersInRange:NSMakeRange(0, 1) withString:[[selectorString substringToIndex:1] uppercaseString]]; - [selectorString insertString:@"set" atIndex:0]; - - // if the property has 1 or more axis parts, we need to take those into account, too - if ([[anInvocation methodSignature] numberOfArguments] > 2) { - const NSRange colonRange = [selectorString rangeOfString:@":"]; - const NSRange forRange = [selectorString rangeOfString:@"For"]; - - if (colonRange.location != NSNotFound && forRange.location != NSNotFound && colonRange.location > NSMaxRange(forRange)) { - const NSRange axisNameRange = NSMakeRange(forRange.location+3, colonRange.location-forRange.location-3); - NSString *axisName = [selectorString substringWithRange:axisNameRange]; - axisName = [axisName stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:[[axisName substringToIndex:1] uppercaseString]]; - NSString *axisSelectorPartName = [NSString stringWithFormat:@"for%@:", axisName]; - [selectorString insertString:axisSelectorPartName atIndex:NSMaxRange(colonRange)]; - [selectorString replaceCharactersInRange:NSMakeRange(forRange.location, colonRange.location-forRange.location) withString:@""]; - } - } else { - [selectorString appendString:@":"]; - } - - // now build a key based on the generated setter selector and the given axis arguments and fetch the matching stored property value - UIAppearanceProperty *key = [[UIAppearanceProperty alloc] initWithSelector:NSSelectorFromString(selectorString) axisValues:argumentValues]; - NSValue *propertyValue = [_settings objectForKey:key]; - - // setup a return data buffer and zero it - const NSUInteger returnLength = [[anInvocation methodSignature] methodReturnLength]; - UInt8 returnData[returnLength]; - memset(returnData, 0, returnLength); - - // fetch the value and return it - if there is none, this ends up returning a zeroed data structure - [propertyValue getValue:returnData]; - [anInvocation setReturnValue:returnData]; - - [key release]; - [selectorString release]; - } else { + } + else { // derp [self doesNotRecognizeSelector:[anInvocation selector]]; } @@ -376,7 +358,7 @@ - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector - (NSDictionary *)_appearancePropertiesAndValues { - return [[_settings copy] autorelease]; + return [_settings copy]; } @end diff --git a/UIKit/Classes/UIApplication.h b/UIKit/Classes/UIApplication.h index d72a1f25..1ee7e7f9 100644 --- a/UIKit/Classes/UIApplication.h +++ b/UIKit/Classes/UIApplication.h @@ -51,18 +51,34 @@ extern NSString *const UIApplicationDidReceiveMemoryWarningNotification; extern NSString *const UITrackingRunLoopMode; -typedef enum { +typedef NS_ENUM(NSInteger, UIStatusBarStyle) { UIStatusBarStyleDefault, UIStatusBarStyleBlackTranslucent, UIStatusBarStyleBlackOpaque -} UIStatusBarStyle; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIStatusBarAnimation) { + UIStatusBarAnimationNone, + UIStatusBarAnimationFade, + UIStatusBarAnimationSlide, +}; + +typedef NS_ENUM(NSInteger, UIInterfaceOrientation) { UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait, UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight, UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft -} UIInterfaceOrientation; +}; + +typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) { + UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait), + UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft), + UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight), + UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown), + UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), + UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown), + UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight), +}; #define UIInterfaceOrientationIsPortrait(orientation) \ ((orientation) == UIInterfaceOrientationPortrait || \ @@ -73,12 +89,13 @@ typedef enum { (orientation) == UIInterfaceOrientationLandscapeRight) // push is not gonna work in mac os, unless you are apple (facetime) -typedef enum { - UIRemoteNotificationTypeNone = 0, - UIRemoteNotificationTypeBadge = 1 << 0, - UIRemoteNotificationTypeSound = 1 << 1, - UIRemoteNotificationTypeAlert = 1 << 2 -} UIRemoteNotificationType; +typedef NS_OPTIONS(NSUInteger, UIRemoteNotificationType) { + UIRemoteNotificationTypeNone = 0, + UIRemoteNotificationTypeBadge = 1 << 0, + UIRemoteNotificationTypeSound = 1 << 1, + UIRemoteNotificationTypeAlert = 1 << 2, + UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3 +}; // whenever the NSApplication is no longer "active" from OSX's point of view, your UIApplication instance // will switch to UIApplicationStateInactive. This happens when the app is no longer in the foreground, for instance. @@ -101,11 +118,11 @@ typedef enum { // guarentee that your expiration handler will even be called. additionally, the reliability of your network is certainly // going to be suspect when entering sleep as well. so be aware - but basically these same constraints exist on iOS so // in many respects it shouldn't affect your code much or at all. -typedef enum { +typedef NS_ENUM(NSInteger, UIApplicationState) { UIApplicationStateActive, UIApplicationStateInactive, UIApplicationStateBackground -} UIApplicationState; +}; typedef NSUInteger UIBackgroundTaskIdentifier; @@ -114,22 +131,7 @@ extern const NSTimeInterval UIMinimumKeepAliveTimeout; @class UIWindow, UIApplication, UILocalNotification; -@interface UIApplication : UIResponder { -@private - UIEvent *_currentEvent; - UIWindow *_keyWindow; - NSMutableSet *_visibleWindows; - UIApplicationState _applicationState; - __unsafe_unretained id _delegate; - BOOL _idleTimerDisabled; - BOOL _networkActivityIndicatorVisible; - BOOL _applicationSupportsShakeToEdit; - NSUInteger _ignoringInteractionEvents; - NSInteger _applicationIconBadgeNumber; - NSDate *_backgroundTasksExpirationDate; - NSMutableArray *_backgroundTasks; -} - +@interface UIApplication : UIResponder + (UIApplication *)sharedApplication; - (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event; @@ -139,6 +141,7 @@ extern const NSTimeInterval UIMinimumKeepAliveTimeout; - (BOOL)canOpenURL:(NSURL *)URL; - (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animated; // no effect +- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation; - (void)beginIgnoringInteractionEvents; - (void)endIgnoringInteractionEvents; @@ -148,10 +151,14 @@ extern const NSTimeInterval UIMinimumKeepAliveTimeout; - (void)cancelLocalNotification:(UILocalNotification *)notification; - (void)cancelAllLocalNotifications; +- (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types; +- (void)unregisterForRemoteNotifications; +- (UIRemoteNotificationType)enabledRemoteNotificationTypes; + - (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^)(void))handler; - (void)endBackgroundTask:(UIBackgroundTaskIdentifier)identifier; -@property (nonatomic, readonly) UIWindow *keyWindow; +@property (nonatomic, weak, readonly) UIWindow *keyWindow; @property (nonatomic, readonly) NSArray *windows; @property (nonatomic, getter=isStatusBarHidden, readonly) BOOL statusBarHidden; @property (nonatomic, readonly) CGRect statusBarFrame; @@ -166,10 +173,18 @@ extern const NSTimeInterval UIMinimumKeepAliveTimeout; @property (nonatomic, readonly) NSTimeInterval backgroundTimeRemaining; // always 0 @property (nonatomic) NSInteger applicationIconBadgeNumber; // no effect, but does set/get the number correctly @property (nonatomic, copy) NSArray *scheduledLocalNotifications; // no effect, returns nil - @end - @interface UIApplication(UIApplicationDeprecated) - (void)setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated __attribute__((deprecated)); // use -setStatusBarHidden:withAnimation: @end + +// This can replace your call to NSApplicationMain. It does not implement NSApplicationMain exactly (and it never calls NSApplicationMain) +// so you should use this with some caution. It does *not* subclass NSApplication but does allow you to subclass UIApplication if you want, +// although that's not really tested so it probably wouldn't work very well. It sets NSApplication's delegate to a very simple dummy object +// which traps -applicationShouldTerminate: to handle background tasks so you don't have to bother with it. Like NSApplicationMain, this +// looks for a NIB file in the Info.plist identified by the NSMainNibFile key and will load it using AppKit's NIB loading stuff. In an +// attempt to make this as confusing as possible, when the main NIB is loaded, it uses the UIApplication (NOT THE NSApplication!) as the +// file's owner! Yep. Insane, I know. I generally do not use NIBs myself, but it's nice for the menu bar. So... yeah... +// NOTE: This does not use NSPrincipalClass from Info.plist since iOS doesn't either, so if that exists in your Info.plist, it is ignored. +extern int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName); diff --git a/UIKit/Classes/UIApplication.m b/UIKit/Classes/UIApplication.m index b9ac380d..6d05dd09 100644 --- a/UIKit/Classes/UIApplication.m +++ b/UIKit/Classes/UIApplication.m @@ -27,18 +27,12 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIApplication+UIPrivate.h" -#import "UIScreen+UIPrivate.h" +#import "UIApplicationAppKitIntegration.h" #import "UIScreenAppKitIntegration.h" -#import "UIKitView.h" -#import "UIEvent+UIPrivate.h" -#import "UITouch+UIPrivate.h" #import "UIWindow+UIPrivate.h" -#import "UIPopoverController+UIPrivate.h" -#import "UIResponderAppKitIntegration.h" -#import "UIApplicationAppKitIntegration.h" -#import "UIKey+UIPrivate.h" +#import "UIKitView.h" #import "UIBackgroundTask.h" +#import "UINSApplicationDelegate.h" #import NSString *const UIApplicationWillChangeStatusBarOrientationNotification = @"UIApplicationWillChangeStatusBarOrientationNotification"; @@ -68,86 +62,31 @@ static UIApplication *_theApplication = nil; -static CGPoint ScreenLocationFromNSEvent(UIScreen *theScreen, NSEvent *theNSEvent) -{ - CGPoint screenLocation = NSPointToCGPoint([[theScreen UIKitView] convertPoint:[theNSEvent locationInWindow] fromView:nil]); - if (![[theScreen UIKitView] isFlipped]) { - // the y coord from the NSView might be inverted - screenLocation.y = theScreen.bounds.size.height - screenLocation.y - 1; - } - return screenLocation; -} - -static CGPoint ScrollDeltaFromNSEvent(NSEvent *theNSEvent) -{ - double dx, dy; - - CGEventRef cgEvent = [theNSEvent CGEvent]; - const int64_t isContinious = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventIsContinuous); - - if (isContinious == 0) { - CGEventSourceRef source = CGEventCreateSourceFromEvent(cgEvent); - double pixelsPerLine; - - if (source) { - pixelsPerLine = CGEventSourceGetPixelsPerLine(source); - CFRelease(source); - } else { - // docs often say things like, "the default is near 10" so it seems reasonable that if the source doesn't work - // for some reason to fetch the pixels per line, then 10 is probably a decent fallback value. :) - pixelsPerLine = 10; - } - - dx = CGEventGetDoubleValueField(cgEvent, kCGScrollWheelEventFixedPtDeltaAxis2) * pixelsPerLine; - dy = CGEventGetDoubleValueField(cgEvent, kCGScrollWheelEventFixedPtDeltaAxis1) * pixelsPerLine; - } else { - dx = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2); - dy = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); - } - - return CGPointMake(-dx, -dy); -} - -static BOOL TouchIsActiveGesture(UITouch *touch) -{ - return (touch.phase == _UITouchPhaseGestureBegan || touch.phase == _UITouchPhaseGestureChanged); -} - -static BOOL TouchIsActiveNonGesture(UITouch *touch) -{ - return (touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseMoved || touch.phase == UITouchPhaseStationary); -} - -static BOOL TouchIsActive(UITouch *touch) -{ - return TouchIsActiveGesture(touch) || TouchIsActiveNonGesture(touch); -} - -@implementation UIApplication -@synthesize keyWindow=_keyWindow, delegate=_delegate, idleTimerDisabled=_idleTimerDisabled, applicationSupportsShakeToEdit=_applicationSupportsShakeToEdit; -@synthesize applicationIconBadgeNumber = _applicationIconBadgeNumber, applicationState=_applicationState; - -+ (void)initialize -{ - if (self == [UIApplication class]) { - _theApplication = [[UIApplication alloc] init]; - } +@implementation UIApplication { + NSUInteger _ignoringInteractionEvents; + NSDate *_backgroundTasksExpirationDate; + NSMutableArray *_backgroundTasks; } + (UIApplication *)sharedApplication { + if (!_theApplication) { + _theApplication = [[self alloc] init]; + } + return _theApplication; } - (id)init { if ((self=[super init])) { - _currentEvent = [[UIEvent alloc] initWithEventType:UIEventTypeTouches]; - [_currentEvent _setTouch:[[[UITouch alloc] init] autorelease]]; - _visibleWindows = [[NSMutableSet alloc] init]; _backgroundTasks = [[NSMutableArray alloc] init]; _applicationState = UIApplicationStateActive; _applicationSupportsShakeToEdit = YES; // yeah... not *really* true, but UIKit defaults to YES :) + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillFinishLaunching:) name:NSApplicationWillFinishLaunchingNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationDidFinishLaunching:) name:NSApplicationDidFinishLaunchingNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillTerminate:) name:NSApplicationWillTerminateNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillResignActive:) name:NSApplicationWillResignActiveNotification object:nil]; @@ -166,11 +105,6 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; - [_currentEvent release]; - [_visibleWindows release]; - [_backgroundTasks release]; - [_backgroundTasksExpirationDate release]; - [super dealloc]; } - (NSTimeInterval)statusBarOrientationAnimationDuration @@ -193,11 +127,6 @@ - (NSTimeInterval)backgroundTimeRemaining return [_backgroundTasksExpirationDate timeIntervalSinceNow]; } -- (BOOL)isNetworkActivityIndicatorVisible -{ - return _networkActivityIndicatorVisible; -} - - (void)setNetworkActivityIndicatorVisible:(BOOL)b { if (b != [self isNetworkActivityIndicatorVisible]) { @@ -243,6 +172,23 @@ - (void)setStatusBarStyle:(UIStatusBarStyle)statusBarStyle animated:(BOOL)animat { } +- (void)setStatusBarHidden:(BOOL)hidden withAnimation:(UIStatusBarAnimation)animation +{ +} + +- (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types +{ +} + +- (void)unregisterForRemoteNotifications +{ +} + +- (UIRemoteNotificationType)enabledRemoteNotificationTypes +{ + return UIRemoteNotificationTypeNone; +} + - (void)presentLocalNotificationNow:(UILocalNotification *)notification { } @@ -266,7 +212,7 @@ - (void)setScheduledLocalNotifications:(NSArray *)scheduledLocalNotifications - (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^)(void))handler { - UIBackgroundTask *task = [[[UIBackgroundTask alloc] initWithExpirationHandler:handler] autorelease]; + UIBackgroundTask *task = [[UIBackgroundTask alloc] initWithExpirationHandler:handler]; [_backgroundTasks addObject:task]; return task.taskIdentifier; } @@ -335,7 +281,7 @@ - (BOOL)_runRunLoopForBackgroundTasksBeforeDate:(NSDate *)date - (void)_cancelBackgroundTasks { // if there's any remaining tasks, run their expiration handlers - for (UIBackgroundTask *task in [[_backgroundTasks copy] autorelease]) { + for (UIBackgroundTask *task in [_backgroundTasks copy]) { if (task.expirationHandler) { task.expirationHandler(); } @@ -354,8 +300,7 @@ - (NSApplicationTerminateReply)terminateApplicationBeforeDate:(NSDate *)timeoutD { [self _enterBackground]; - [_backgroundTasksExpirationDate release]; - _backgroundTasksExpirationDate = [timeoutDate retain]; + _backgroundTasksExpirationDate = timeoutDate; // we will briefly block here for a short time and run the runloop in an attempt to let the background tasks finish up before // actually prompting the user with an annoying alert. users are much more used to an app hanging for a brief moment while @@ -375,7 +320,6 @@ - (NSApplicationTerminateReply)terminateApplicationBeforeDate:(NSDate *)timeoutD [self _cancelBackgroundTasks]; // and reset our timer since we're done - [_backgroundTasksExpirationDate release]; _backgroundTasksExpirationDate = nil; // and return @@ -411,7 +355,6 @@ - (NSApplicationTerminateReply)terminateApplicationBeforeDate:(NSDate *)timeoutD [self _cancelBackgroundTasks]; // and reset our timer since we're done - [_backgroundTasksExpirationDate release]; _backgroundTasksExpirationDate = nil; // now just in case all of this happened too quickly and the user might not have had time to read and understand the alert, @@ -424,7 +367,6 @@ - (NSApplicationTerminateReply)terminateApplicationBeforeDate:(NSDate *)timeoutD } } - [alert release]; [NSApp endModalSession:session]; @@ -436,7 +378,7 @@ - (NSApplicationTerminateReply)terminateApplicationBeforeDate:(NSDate *)timeoutD // because we're probably in that run loop mode due to how -applicationShouldTerminate: does things. I don't // know if I could do this same thing with a couple of simple GCD calls, but whatever, this works too. :) [self performSelectorOnMainThread:@selector(_runBackgroundTasks:) - withObject:[[taskFinisher copy] autorelease] + withObject:[taskFinisher copy] waitUntilDone:NO modes:[NSArray arrayWithObjects:NSModalPanelRunLoopMode, NSRunLoopCommonModes, nil]]; @@ -453,7 +395,6 @@ - (void)_computerWillSleep:(NSNotification *)note // the machine is about to go to sleep.. so we'll just do things in a blocking way in this case while still handling // any pending background tasks. - [_backgroundTasksExpirationDate release]; _backgroundTasksExpirationDate = [[NSDate alloc] initWithTimeIntervalSinceNow:29]; for (;;) { @@ -465,7 +406,6 @@ - (void)_computerWillSleep:(NSNotification *)note [self _cancelBackgroundTasks]; // and reset our timer since we're done - [_backgroundTasksExpirationDate release]; _backgroundTasksExpirationDate = nil; } } @@ -475,36 +415,26 @@ - (void)_computerDidWakeUp:(NSNotification *)note [self _enterForeground]; } -- (void)_setKeyWindow:(UIWindow *)newKeyWindow +- (NSArray *)windows { - _keyWindow = newKeyWindow; - - if (_keyWindow) { - // this will make the NSView that the key window lives on the first responder in its NSWindow - // highly confusing, but I think this is mostly the correct thing to do - // when a UIView is made first responder, it also tells its window to become the key window - // which means that we can ultimately end up here and if keyboard stuff is to work as expected - // (for example) the underlying NSView really needs to be the first responder as far as AppKit - // is concerned. this is all very confusing in my mind right now, but I think it makes sense. - [[[_keyWindow.screen UIKitView] window] makeFirstResponder:[_keyWindow.screen UIKitView]]; + NSMutableArray *windows = [NSMutableArray new]; + + for (UIScreen *screen in [UIScreen screens]) { + [windows addObjectsFromArray:screen.windows]; } + + return [windows sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"windowLevel" ascending:YES]]]; } -- (void)_windowDidBecomeVisible:(UIWindow *)theWindow -{ - [_visibleWindows addObject:[NSValue valueWithNonretainedObject:theWindow]]; -} - -- (void)_windowDidBecomeHidden:(UIWindow *)theWindow -{ - if (theWindow == _keyWindow) [self _setKeyWindow:nil]; - [_visibleWindows removeObject:[NSValue valueWithNonretainedObject:theWindow]]; -} - -- (NSArray *)windows +- (UIWindow *)keyWindow { - NSSortDescriptor *sort = [[[NSSortDescriptor alloc] initWithKey:@"windowLevel" ascending:YES] autorelease]; - return [[_visibleWindows valueForKey:@"nonretainedObjectValue"] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]]; + for (UIWindow *window in self.windows) { + if (window.isKeyWindow) { + return window; + } + } + + return nil; } - (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event @@ -542,47 +472,21 @@ - (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent * } if (target) { - [target performSelector:action withObject:sender withObject:event]; + typedef void(*EventActionMethod)(id, SEL, id, UIEvent *); + EventActionMethod method = (EventActionMethod)[target methodForSelector:action]; + method(target, action, sender, event); return YES; - } else { - return NO; - } -} - -- (UIResponder *)_firstResponderForScreen:(UIScreen *)screen -{ - if (_keyWindow.screen == screen) { - return [_keyWindow _firstResponder]; - } else { - return nil; - } -} - -- (BOOL)_sendActionToFirstResponder:(SEL)action withSender:(id)sender fromScreen:(UIScreen *)theScreen -{ - UIResponder *responder = [self _firstResponderForScreen:theScreen]; - - while (responder) { - if ([responder respondsToSelector:action]) { - [responder performSelector:action withObject:sender]; - return YES; - } else { - responder = [responder nextResponder]; - } } return NO; } -- (BOOL)_firstResponderCanPerformAction:(SEL)action withSender:(id)sender fromScreen:(UIScreen *)theScreen -{ - return [[self _firstResponderForScreen:theScreen] canPerformAction:action withSender:sender]; -} - - (void)sendEvent:(UIEvent *)event { - for (UITouch *touch in [event allTouches]) { - [touch.window sendEvent:event]; + if (event.type == UIEventTypeTouches) { + [self.windows makeObjectsPerformSelector:@selector(sendEvent:) withObject:event]; + } else { + [self.keyWindow sendEvent:event]; } } @@ -596,204 +500,42 @@ - (BOOL)canOpenURL:(NSURL *)url return (url? [[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:url] : nil) != nil; } -- (BOOL)_sendGlobalKeyboardNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *)theScreen +- (void)_applicationWillFinishLaunching:(NSNotification *)note { - if (![self isIgnoringInteractionEvents]) { - UIKey *key = [[[UIKey alloc] initWithNSEvent:theNSEvent] autorelease]; - - if (key.type == UIKeyTypeEnter || (key.commandKeyPressed && key.type == UIKeyTypeReturn)) { - if ([self _firstResponderCanPerformAction:@selector(commit:) withSender:key fromScreen:theScreen]) { - return [self _sendActionToFirstResponder:@selector(commit:) withSender:key fromScreen:theScreen]; - } - } - } + NSDictionary *options = nil; - return NO; -} - -- (BOOL)_sendKeyboardNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *)theScreen -{ - if (![self isIgnoringInteractionEvents]) { - if (![self _sendGlobalKeyboardNSEvent:theNSEvent fromScreen:theScreen]) { - UIResponder *firstResponder = [self _firstResponderForScreen:theScreen]; - - if (firstResponder) { - UIKey *key = [[[UIKey alloc] initWithNSEvent:theNSEvent] autorelease]; - UIEvent *event = [[[UIEvent alloc] initWithEventType:UIEventTypeKeyPress] autorelease]; - [event _setTimestamp:[theNSEvent timestamp]]; - - [firstResponder keyPressed:key withEvent:event]; - return ![event _isUnhandledKeyPressEvent]; - } - } + if ([_delegate respondsToSelector:@selector(application:willFinishLaunchingOnDesktopWithOptions:)]) { + [_delegate application:self willFinishLaunchingOnDesktopWithOptions:options]; } - return NO; -} - -- (void)_setCurrentEventTouchedViewWithNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *)theScreen -{ - const CGPoint screenLocation = ScreenLocationFromNSEvent(theScreen, theNSEvent); - UITouch *touch = [[_currentEvent allTouches] anyObject]; - UIView *previousView = [touch.view retain]; - - [touch _setTouchedView:[theScreen _hitTest:screenLocation event:_currentEvent]]; - - if (touch.view != previousView) { - [previousView mouseExitedView:previousView enteredView:touch.view withEvent:_currentEvent]; - [touch.view mouseExitedView:previousView enteredView:touch.view withEvent:_currentEvent]; + if ([_delegate respondsToSelector:@selector(application:willFinishLaunchingWithOptions:)]) { + [_delegate application:self willFinishLaunchingWithOptions:options]; } - - [previousView release]; } -- (void)_sendMouseNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *)theScreen +- (void)_applicationDidFinishLaunching:(NSNotification *)note { - UITouch *touch = [[_currentEvent allTouches] anyObject]; - - [_currentEvent _setTimestamp:[theNSEvent timestamp]]; - - const NSTimeInterval timestamp = [theNSEvent timestamp]; - const CGPoint screenLocation = ScreenLocationFromNSEvent(theScreen, theNSEvent); - - // this is a special case to cancel any existing gestures (as far as the client code is concerned) if a mouse - // button is pressed mid-gesture. the reason is that sometimes when using a magic mouse a user will intend to - // click but if their finger moves against the surface ever so slightly, it will trigger a touch gesture to - // begin instead. without this, the fact that we're in a touch gesture phase effectively overrules everything - // else and clicks end up not getting registered. I don't think it's right to allow clicks to pass through when - // we're in a gesture state since that'd be somewhat like a multitouch scenerio on a real iOS device and we're - // not supporting anything like that at the moment. - if (TouchIsActiveGesture(touch) && ([theNSEvent type] == NSLeftMouseDown || [theNSEvent type] == NSRightMouseDown)) { - [touch _updatePhase:_UITouchPhaseGestureEnded screenLocation:screenLocation timestamp:timestamp]; - [self sendEvent:_currentEvent]; - } - - if (TouchIsActiveNonGesture(touch)) { - switch ([theNSEvent type]) { - case NSLeftMouseUp: - [touch _updatePhase:UITouchPhaseEnded screenLocation:screenLocation timestamp:timestamp]; - [self sendEvent:_currentEvent]; - break; - - case NSLeftMouseDragged: - [touch _updatePhase:UITouchPhaseMoved screenLocation:screenLocation timestamp:timestamp]; - [self sendEvent:_currentEvent]; - break; - } - } else if (TouchIsActiveGesture(touch)) { - switch ([theNSEvent type]) { - case NSEventTypeEndGesture: - [touch _updatePhase:_UITouchPhaseGestureEnded screenLocation:screenLocation timestamp:timestamp]; - [self sendEvent:_currentEvent]; - break; - - case NSScrollWheel: - // when captured here, the scroll wheel event had to have been part of a gesture - in other words it is a - // touch device scroll event and is therefore mapped to UIPanGestureRecognizer. - [touch _updateGesture:_UITouchGesturePan screenLocation:screenLocation delta:ScrollDeltaFromNSEvent(theNSEvent) rotation:0 magnification:0 timestamp:timestamp]; - [self sendEvent:_currentEvent]; - break; - - case NSEventTypeMagnify: - [touch _updateGesture:_UITouchGesturePinch screenLocation:screenLocation delta:CGPointZero rotation:0 magnification:[theNSEvent magnification] timestamp:timestamp]; - [self sendEvent:_currentEvent]; - break; - - case NSEventTypeRotate: - [touch _updateGesture:_UITouchGestureRotation screenLocation:screenLocation delta:CGPointZero rotation:[theNSEvent rotation] magnification:0 timestamp:timestamp]; - [self sendEvent:_currentEvent]; - break; - - case NSEventTypeSwipe: - [touch _updateGesture:_UITouchGestureSwipe screenLocation:screenLocation delta:ScrollDeltaFromNSEvent(theNSEvent) rotation:0 magnification:0 timestamp:timestamp]; - [self sendEvent:_currentEvent]; - break; - } - } else if (![self isIgnoringInteractionEvents]) { - switch ([theNSEvent type]) { - case NSLeftMouseDown: - [touch _setPhase:UITouchPhaseBegan screenLocation:screenLocation tapCount:[theNSEvent clickCount] timestamp:timestamp]; - [self _setCurrentEventTouchedViewWithNSEvent:theNSEvent fromScreen:theScreen]; - [self sendEvent:_currentEvent]; - break; - - case NSEventTypeBeginGesture: - [touch _setPhase:_UITouchPhaseGestureBegan screenLocation:screenLocation tapCount:0 timestamp:timestamp]; - [self _setCurrentEventTouchedViewWithNSEvent:theNSEvent fromScreen:theScreen]; - [self sendEvent:_currentEvent]; - break; - - case NSScrollWheel: - // we should only get a scroll wheel event down here if it was done on a non-touch device or was the result of a momentum - // scroll, so they are treated differently so we can tell them apart later in UIPanGestureRecognizer and UIScrollWheelGestureRecognizer - // which are both used by UIScrollView. - [touch _setDiscreteGesture:_UITouchDiscreteGestureScrollWheel screenLocation:screenLocation tapCount:0 delta:ScrollDeltaFromNSEvent(theNSEvent) timestamp:timestamp]; - [self _setCurrentEventTouchedViewWithNSEvent:theNSEvent fromScreen:theScreen]; - [self sendEvent:_currentEvent]; - break; + NSDictionary *options = nil; - case NSRightMouseDown: - [touch _setDiscreteGesture:_UITouchDiscreteGestureRightClick screenLocation:screenLocation tapCount:[theNSEvent clickCount] delta:CGPointZero timestamp:timestamp]; - [self _setCurrentEventTouchedViewWithNSEvent:theNSEvent fromScreen:theScreen]; - [self sendEvent:_currentEvent]; - break; - - case NSMouseMoved: - case NSMouseEntered: - case NSMouseExited: - [touch _setDiscreteGesture:_UITouchDiscreteGestureMouseMove screenLocation:screenLocation tapCount:0 delta:ScrollDeltaFromNSEvent(theNSEvent) timestamp:timestamp]; - [self _setCurrentEventTouchedViewWithNSEvent:theNSEvent fromScreen:theScreen]; - [self sendEvent:_currentEvent]; - break; - } - } -} - -// this is used to cause an interruption/cancel of the current touches. -// Use this when a modal UI element appears (such as a native popup menu), or when a UIPopoverController appears. It seems to make the most sense -// to call _cancelTouches *after* the modal menu has been dismissed, as this causes UI elements to remain in their "pushed" state while the menu -// is being displayed. If that behavior isn't desired, the simple solution is to present the menu from touchesEnded: instead of touchesBegan:. -- (void)_cancelTouches -{ - UITouch *touch = [[_currentEvent allTouches] anyObject]; - const BOOL wasActiveTouch = TouchIsActive(touch); - - [touch _setTouchPhaseCancelled]; - - if (wasActiveTouch) { - [self sendEvent:_currentEvent]; + if ([_delegate respondsToSelector:@selector(application:didFinishLaunchingOnDesktopWithOptions:)]) { + [_delegate application:self didFinishLaunchingOnDesktopWithOptions:options]; } -} -// this sets the touches view property to nil (while retaining the window property setting) -// this is used when a view is removed from its superview while it may have been the origin -// of an active touch. after a view is removed, we don't want to deliver any more touch events -// to it, but we still may need to route the touch itself for the sake of gesture recognizers -// so we need to retain the touch's original window setting so that events can still be routed. -// -// note that the touch itself is not being cancelled here so its phase remains unchanged. -// I'm not entirely certain if that's the correct thing to do, but I think it makes sense. The -// touch itself has not gone anywhere - just the view that it first touched. That breaks the -// delivery of the touch events themselves as far as the usual responder chain delivery is -// concerned, but that appears to be what happens in the real UIKit when you remove a view out -// from under an active touch. -// -// this whole thing is necessary because otherwise a gesture which may have been initiated over -// some specific view would end up getting cancelled/failing if the view under it happens to be -// removed. this is more common than you might expect. a UITableView that is not reusing rows -// does exactly this as it scrolls - which coincidentally is how I found this bug in the first -// place. :P -- (void)_removeViewFromTouches:(UIView *)aView -{ - for (UITouch *touch in [_currentEvent allTouches]) { - if (touch.view == aView) { - [touch _removeFromView]; - } + if ([_delegate respondsToSelector:@selector(application:didFinishLaunchingWithOptions:)]) { + [_delegate application:self didFinishLaunchingWithOptions:options]; + } else if ([_delegate respondsToSelector:@selector(applicationDidFinishLaunching:)]) { + [_delegate applicationDidFinishLaunching:self]; } + + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidFinishLaunchingNotification object:self]; } - (void)_applicationWillTerminate:(NSNotification *)note { + if ([_delegate respondsToSelector:@selector(applicationWillTerminateOnDesktop:)]) { + [_delegate applicationWillTerminateOnDesktop:self]; + } + if ([_delegate respondsToSelector:@selector(applicationWillTerminate:)]) { [_delegate applicationWillTerminate:self]; } @@ -827,6 +569,12 @@ - (void)_applicationDidBecomeActive:(NSNotification *)note } } +// this is only here because there's a real private API in Apple's UIKit that does something similar +- (void)_performMemoryWarning +{ + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidReceiveMemoryWarningNotification object:self]; +} + @end @@ -837,3 +585,65 @@ - (void)setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated } @end + +int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName) +{ + @autoreleasepool { + UIApplication *app = principalClassName? [NSClassFromString(principalClassName) sharedApplication] : [UIApplication sharedApplication]; + id delegate = delegateClassName? [NSClassFromString(delegateClassName) new] : nil; + + [app setDelegate:delegate]; + + NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; + NSString *mainNibName = [infoDictionary objectForKey:@"NSMainNibFile"]; + NSArray *topLevelObjects = nil; + NSNib *mainNib = [[NSNib alloc] initWithNibNamed:mainNibName bundle:[NSBundle mainBundle]]; + + [mainNib instantiateWithOwner:app topLevelObjects:&topLevelObjects]; + + id backgroundTaskCatchingDelegate = [UINSApplicationDelegate new]; + [[NSApplication sharedApplication] setDelegate:backgroundTaskCatchingDelegate]; + [[NSApplication sharedApplication] run]; + + // the only purpose of this is to confuse ARC. I'm not sure how else to do it. + // without this here, ARC thinks it can dealloc some stuff before we're really done + // with it, and since we're never really going to be done with this stuff, it has to + // be kept around as long as the app runs, but since the app never actually gets here + // it will never be executed but this prevents ARC from preemptively releasing things. + // meh. + [@[app, delegate, topLevelObjects, backgroundTaskCatchingDelegate] count]; + } + + // this never happens + return 0; +} + +void UIApplicationSendStationaryTouches(void) +{ + for (UIScreen *screen in [UIScreen screens]) { + [screen.UIKitView sendStationaryTouches]; + } +} + +void UIApplicationInterruptTouchesInView(UIView *view) +{ + // the intent here was that there needed to be a way to force-cancel touches to somewhat replicate situations that + // might arise on OSX that you could kinda/sorta pretend were phonecall-like events where you'd want a touch or + // gesture or something to cancel. these situations come up when things like popovers and modal menus are presented, + // + // If the need arises, my intent here is to send a notification or something on the *next* runloop to all UIKitViews + // attached to screens to tell them to kill off their current touch sequence (if any). It seems important that this + // happen on the *next* runloop cycle and not immediately because there were cases where the touch cancelling would + // happen in response to something like a touch ended event, so we can't just blindly cancel a touch while it's in + // the process of being evalulated since that could lead to very inconsistent behavior and really weird edge cases. + // by deferring the cancel, it would then be able to take the right action if the touch phase was something *other* + // than ended or cancelled by the time it attemped cancellation. + + if (!view) { + for (UIScreen *screen in [UIScreen screens]) { + [screen.UIKitView performSelector:@selector(cancelTouchesInView:) withObject:nil afterDelay:0]; + } + } else { + [view.window.screen.UIKitView performSelector:@selector(cancelTouchesInView:) withObject:view afterDelay:0]; + } +} diff --git a/UIKit/Classes/UIApplicationAppKitIntegration.h b/UIKit/Classes/UIApplicationAppKitIntegration.h index 9c9d158d..1c425e16 100644 --- a/UIKit/Classes/UIApplicationAppKitIntegration.h +++ b/UIKit/Classes/UIApplicationAppKitIntegration.h @@ -54,3 +54,9 @@ extern NSString *const UIApplicationNetworkActivityIndicatorChangedNotification; - (NSApplicationTerminateReply)terminateApplicationBeforeDate:(NSDate *)timeoutDate; @end + +// these are probably more internal the meant to be used publically, but just in case... here they are. +extern void UIApplicationInterruptTouchesInView(UIView *view); +extern void UIApplicationSendStationaryTouches(void); + + diff --git a/UIKit/Classes/UIApplicationDelegate.h b/UIKit/Classes/UIApplicationDelegate.h index fe094838..aa4f78a6 100644 --- a/UIKit/Classes/UIApplicationDelegate.h +++ b/UIKit/Classes/UIApplicationDelegate.h @@ -33,12 +33,22 @@ @protocol UIApplicationDelegate @optional +- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; -- (void)applicationDidFinishLaunching:(UIApplication *)application; +- (void)applicationDidFinishLaunching:(UIApplication *)application; // not recommended - (void)applicationDidBecomeActive:(UIApplication *)application; - (void)applicationWillResignActive:(UIApplication *)application; - (void)applicationWillTerminate:(UIApplication *)application; - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; - (void)applicationDidEnterBackground:(UIApplication *)application; - (void)applicationWillEnterForeground:(UIApplication *)application; + +// non-standard + +// these are all called immediately before the normal delegate methods of similar name +// these do NOT supercede the normal methods, if the normal ones also exist, they are also called! +- (void)application:(UIApplication *)application willFinishLaunchingOnDesktopWithOptions:(NSDictionary *)launchOptions; +- (void)application:(UIApplication *)application didFinishLaunchingOnDesktopWithOptions:(NSDictionary *)launchOptions; +- (void)applicationWillTerminateOnDesktop:(UIApplication *)application; + @end diff --git a/UIKit/Classes/UIBackgroundTask.h b/UIKit/Classes/UIBackgroundTask.h index 5805bf0f..dc55e8f6 100644 --- a/UIKit/Classes/UIBackgroundTask.h +++ b/UIKit/Classes/UIBackgroundTask.h @@ -29,14 +29,11 @@ #import "UIApplication.h" -@interface UIBackgroundTask : NSObject { - void (^_expirationHandler)(void); - UIBackgroundTaskIdentifier _taskIdentifier; -} +@interface UIBackgroundTask : NSObject - (id)initWithExpirationHandler:(void(^)(void))handler; -@property (nonatomic, readonly) void (^expirationHandler)(void); +@property (copy, nonatomic, readonly) void (^expirationHandler)(void); @property (nonatomic, readonly) UIBackgroundTaskIdentifier taskIdentifier; @end diff --git a/UIKit/Classes/UIBackgroundTask.m b/UIKit/Classes/UIBackgroundTask.m index 70997f10..9a555fda 100644 --- a/UIKit/Classes/UIBackgroundTask.m +++ b/UIKit/Classes/UIBackgroundTask.m @@ -30,7 +30,6 @@ #import "UIBackgroundTask.h" @implementation UIBackgroundTask -@synthesize expirationHandler=_expirationHandler, taskIdentifier=_taskIdentifier; - (id)initWithExpirationHandler:(void(^)(void))handler { @@ -42,10 +41,5 @@ - (id)initWithExpirationHandler:(void(^)(void))handler return self; } -- (void)dealloc -{ - [_expirationHandler release]; - [super dealloc]; -} @end diff --git a/UIKit/Classes/UIBarButtonItem.h b/UIKit/Classes/UIBarButtonItem.h index 9de8fc96..dfeddf0d 100644 --- a/UIKit/Classes/UIBarButtonItem.h +++ b/UIKit/Classes/UIBarButtonItem.h @@ -28,8 +28,9 @@ */ #import "UIBarItem.h" +#import "UIInterface.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIBarButtonSystemItem) { UIBarButtonSystemItemDone, UIBarButtonSystemItemCancel, UIBarButtonSystemItemEdit, @@ -53,25 +54,20 @@ typedef enum { UIBarButtonSystemItemFastForward, UIBarButtonSystemItemUndo, // iPhoneOS 3.0 UIBarButtonSystemItemRedo, // iPhoneOS 3.0 -} UIBarButtonSystemItem; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIBarButtonItemStyle) { UIBarButtonItemStylePlain, UIBarButtonItemStyleBordered, UIBarButtonItemStyleDone, -} UIBarButtonItemStyle; +}; @class UIView, UIImage; @interface UIBarButtonItem : UIBarItem { @package - CGFloat _width; - UIView *_customView; - __unsafe_unretained id _target; - SEL _action; BOOL _isSystemItem; UIBarButtonSystemItem _systemItem; - UIBarButtonItemStyle _style; } - (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action; @@ -79,10 +75,25 @@ typedef enum { - (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action; - (id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action; +- (UIImage *)backButtonBackgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics; +- (void)setBackButtonBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics; +- (UIOffset)backButtonTitlePositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics; +- (void)setBackButtonTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics; +- (CGFloat)backButtonBackgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics; +- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics; +- (CGFloat)backgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics; +- (void)setBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics; +- (UIImage *)backgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics; +- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics; +- (UIImage *)backgroundImageForState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics; +- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics; +- (UIOffset)titlePositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics; +- (void)setTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics; + @property (nonatomic) UIBarButtonItemStyle style; @property (nonatomic) CGFloat width; -@property (nonatomic, retain) UIView *customView; +@property (nonatomic, strong) UIView *customView; @property (nonatomic, assign) id target; @property (nonatomic) SEL action; - +@property (nonatomic, strong) UIColor *tintColor; @end diff --git a/UIKit/Classes/UIBarButtonItem.m b/UIKit/Classes/UIBarButtonItem.m index 2054a05a..7ef0f341 100644 --- a/UIKit/Classes/UIBarButtonItem.m +++ b/UIKit/Classes/UIBarButtonItem.m @@ -31,7 +31,6 @@ #import "UIView.h" @implementation UIBarButtonItem -@synthesize width=_width, customView=_customView, action=_action, target=_target, style=_style; - (id)init { @@ -84,15 +83,73 @@ - (id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(i return self; } -- (void)dealloc -{ - [_customView release]; - [super dealloc]; -} - (UIView *)customView { return _isSystemItem? nil : _customView; } +- (UIImage *)backButtonBackgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics +{ + return nil; +} + +- (void)setBackButtonBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics +{ +} + +- (UIOffset)backButtonTitlePositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics +{ + return UIOffsetZero; +} + +- (void)setBackButtonTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics +{ +} + +- (CGFloat)backButtonBackgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics +{ + return 0; +} + +- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics +{ +} + +- (CGFloat)backgroundVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics +{ + return 0; +} + +- (void)setBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics +{ +} + +- (UIImage *)backgroundImageForState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics +{ + return nil; +} + +- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics +{ +} + +- (UIImage *)backgroundImageForState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics +{ + return nil; +} + +- (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state style:(UIBarButtonItemStyle)style barMetrics:(UIBarMetrics)barMetrics +{ +} + +- (UIOffset)titlePositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics +{ + return UIOffsetZero; +} + +- (void)setTitlePositionAdjustment:(UIOffset)adjustment forBarMetrics:(UIBarMetrics)barMetrics +{ +} + @end diff --git a/UIKit/Classes/UIBarItem.h b/UIKit/Classes/UIBarItem.h index c27fe69c..2db53b00 100644 --- a/UIKit/Classes/UIBarItem.h +++ b/UIKit/Classes/UIBarItem.h @@ -31,22 +31,13 @@ @class UIImage; -@interface UIBarItem : NSObject { -@private - BOOL _enabled; - UIImage *_image; - UIEdgeInsets _imageInsets; - NSString *_title; - NSInteger _tag; -} +@interface UIBarItem : NSObject +- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state; +- (NSDictionary *)titleTextAttributesForState:(UIControlState)state; @property (nonatomic, getter=isEnabled) BOOL enabled; -@property (nonatomic, retain) UIImage *image; +@property (nonatomic, strong) UIImage *image; @property (nonatomic, assign) UIEdgeInsets imageInsets; @property (nonatomic, copy) NSString *title; @property (nonatomic) NSInteger tag; - -- (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state; -- (NSDictionary *)titleTextAttributesForState:(UIControlState)state; - @end diff --git a/UIKit/Classes/UIBarItem.m b/UIKit/Classes/UIBarItem.m index cd19a5e9..e417420d 100644 --- a/UIKit/Classes/UIBarItem.m +++ b/UIKit/Classes/UIBarItem.m @@ -29,9 +29,9 @@ #import "UIBarItem.h" #import "UIImage.h" +#import "UIAppearanceInstance.h" @implementation UIBarItem -@synthesize enabled=_enabled, image=_image, imageInsets=_imageInsets, title=_title, tag=_tag; - (id)init { @@ -42,12 +42,6 @@ - (id)init return self; } -- (void)dealloc -{ - [_image release]; - [_title release]; - [super dealloc]; -} - (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state { diff --git a/UIKit/Classes/UIBezierPath.h b/UIKit/Classes/UIBezierPath.h index 8ebb18ad..c949a507 100644 --- a/UIKit/Classes/UIBezierPath.h +++ b/UIKit/Classes/UIBezierPath.h @@ -29,29 +29,15 @@ #import -enum { +typedef NS_OPTIONS(NSUInteger, UIRectCorner) { UIRectCornerTopLeft = 1 << 0, UIRectCornerTopRight = 1 << 1, UIRectCornerBottomLeft = 1 << 2, UIRectCornerBottomRight = 1 << 3, UIRectCornerAllCorners = ~0 }; -typedef NSUInteger UIRectCorner; - -@interface UIBezierPath : NSObject { -@private - CGPathRef _path; - CGFloat _lineWidth; - CGLineCap _lineCapStyle; - CGLineJoin _lineJoinStyle; - CGFloat _miterLimit; - CGFloat _flatness; - BOOL _usesEvenOddFillRule; - CGFloat *_lineDashPattern; - NSInteger _lineDashCount; - CGFloat _lineDashPhase; -} +@interface UIBezierPath : NSObject + (UIBezierPath *)bezierPath; + (UIBezierPath *)bezierPathWithRect:(CGRect)rect; + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect; @@ -68,33 +54,24 @@ typedef NSUInteger UIRectCorner; - (void)closePath; - (void)removeAllPoints; - (void)appendPath:(UIBezierPath *)bezierPath; - -@property (nonatomic) CGPathRef CGPath; -@property (nonatomic, readonly) CGPoint currentPoint; - -@property (nonatomic) CGFloat lineWidth; -@property (nonatomic) CGLineCap lineCapStyle; -@property (nonatomic) CGLineJoin lineJoinStyle; -@property (nonatomic) CGFloat miterLimit; -@property (nonatomic) CGFloat flatness; -@property (nonatomic) BOOL usesEvenOddFillRule; - - (void)setLineDash:(const CGFloat *)pattern count:(NSInteger)count phase:(CGFloat)phase; - (void)getLineDash:(CGFloat *)pattern count:(NSInteger *)count phase:(CGFloat *)phase; - - (void)fill; - (void)fillWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha; - - (void)stroke; - (void)strokeWithBlendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha; - - (void)addClip; - - (BOOL)containsPoint:(CGPoint)point; +- (void)applyTransform:(CGAffineTransform)transform; +@property (nonatomic) CGPathRef CGPath; +@property (nonatomic, readonly) CGPoint currentPoint; +@property (nonatomic) CGFloat lineWidth; +@property (nonatomic) CGLineCap lineCapStyle; +@property (nonatomic) CGLineJoin lineJoinStyle; +@property (nonatomic) CGFloat miterLimit; +@property (nonatomic) CGFloat flatness; +@property (nonatomic) BOOL usesEvenOddFillRule; @property (readonly, getter=isEmpty) BOOL empty; @property (nonatomic, readonly) CGRect bounds; - -- (void)applyTransform:(CGAffineTransform)transform; - @end diff --git a/UIKit/Classes/UIBezierPath.m b/UIKit/Classes/UIBezierPath.m index a21993a8..f100b989 100644 --- a/UIKit/Classes/UIBezierPath.m +++ b/UIKit/Classes/UIBezierPath.m @@ -30,9 +30,12 @@ #import "UIBezierPath.h" #import "UIGraphics.h" -@implementation UIBezierPath -@synthesize lineWidth=_lineWidth, lineCapStyle=_lineCapStyle, lineJoinStyle=_lineJoinStyle, miterLimit=_miterLimit; -@synthesize flatness=_flatness, usesEvenOddFillRule=_usesEvenOddFillRule, CGPath=_path; +@implementation UIBezierPath { + CGFloat *_lineDashPattern; + NSInteger _lineDashCount; + CGFloat _lineDashPhase; +} +@synthesize CGPath=_path; - (id)init { @@ -53,7 +56,32 @@ - (id)init - (void)dealloc { if (_path) CGPathRelease(_path); - [super dealloc]; +} + +- (id)copyWithZone:(NSZone *)zone +{ + UIBezierPath *copy = [[self class] new]; + + copy.CGPath = self.CGPath; + copy.lineWidth = self.lineWidth; + copy.lineCapStyle = self.lineCapStyle; + copy.lineJoinStyle = self.lineJoinStyle; + copy.miterLimit = self.miterLimit; + copy.flatness = self.flatness; + copy.usesEvenOddFillRule = self.usesEvenOddFillRule; + + NSInteger lineDashCount = 0; + [self getLineDash:NULL count:&lineDashCount phase:NULL]; + + if (lineDashCount > 0) { + CGFloat *lineDashPattern = malloc(sizeof(CGFloat) * lineDashCount); + CGFloat lineDashPhase = 0; + [self getLineDash:lineDashPattern count:NULL phase:&lineDashPhase]; + [copy setLineDash:lineDashPattern count:lineDashCount phase:lineDashPhase]; + free(lineDashPattern); + } + + return copy; } + (UIBezierPath *)bezierPathWithCGPath:(CGPathRef)CGPath @@ -61,14 +89,14 @@ + (UIBezierPath *)bezierPathWithCGPath:(CGPathRef)CGPath NSAssert(CGPath != NULL, @"CGPath must not be NULL"); UIBezierPath *bezierPath = [[self alloc] init]; bezierPath.CGPath = CGPath; - return [bezierPath autorelease]; + return bezierPath; } + (UIBezierPath *)bezierPath { UIBezierPath *bezierPath = [[self alloc] init]; bezierPath->_path = CGPathCreateMutable(); - return [bezierPath autorelease]; + return bezierPath; } + (UIBezierPath *)bezierPathWithRect:(CGRect)rect @@ -78,7 +106,7 @@ + (UIBezierPath *)bezierPathWithRect:(CGRect)rect UIBezierPath *bezierPath = [[self alloc] init]; bezierPath->_path = path; - return [bezierPath autorelease]; + return bezierPath; } + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect @@ -88,7 +116,7 @@ + (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect UIBezierPath *bezierPath = [[self alloc] init]; bezierPath->_path = path; - return [bezierPath autorelease]; + return bezierPath; } + (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius @@ -143,7 +171,7 @@ + (UIBezierPath *)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRe UIBezierPath *bezierPath = [[self alloc] init]; bezierPath->_path = path; - return [bezierPath autorelease]; + return bezierPath; } + (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise @@ -153,7 +181,7 @@ + (UIBezierPath *)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius UIBezierPath *bezierPath = [[self alloc] init]; bezierPath->_path = path; - return [bezierPath autorelease]; + return bezierPath; } - (void)moveToPoint:(CGPoint)point diff --git a/UIKit/Classes/UIButton.h b/UIKit/Classes/UIButton.h index d9ecdc3e..27fe1a62 100644 --- a/UIKit/Classes/UIButton.h +++ b/UIKit/Classes/UIButton.h @@ -29,36 +29,21 @@ #import "UIControl.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIButtonType) { UIButtonTypeCustom = 0, UIButtonTypeRoundedRect, UIButtonTypeDetailDisclosure, UIButtonTypeInfoLight, UIButtonTypeInfoDark, UIButtonTypeContactAdd, -} UIButtonType; +}; @class UILabel, UIImageView, UIImage; @interface UIButton : UIControl { -@protected +@package UIButtonType _buttonType; -@private - UILabel *_titleLabel; - UIImageView *_imageView; - UIImageView *_backgroundImageView; - BOOL _reversesTitleShadowWhenHighlighted; - BOOL _adjustsImageWhenHighlighted; - BOOL _adjustsImageWhenDisabled; - BOOL _showsTouchWhenHighlighted; - UIEdgeInsets _contentEdgeInsets; - UIEdgeInsets _titleEdgeInsets; - UIEdgeInsets _imageEdgeInsets; - NSMutableDictionary *_content; - UIImage *_adjustedHighlightImage; - UIImage *_adjustedDisabledImage; } - + (id)buttonWithType:(UIButtonType)buttonType; - (void)setTitle:(NSString *)title forState:(UIControlState)state; @@ -79,8 +64,8 @@ typedef enum { - (CGRect)imageRectForContentRect:(CGRect)contentRect; @property (nonatomic, readonly) UIButtonType buttonType; -@property (nonatomic,readonly,retain) UILabel *titleLabel; -@property (nonatomic,readonly,retain) UIImageView *imageView; +@property (nonatomic,readonly,strong) UILabel *titleLabel; +@property (nonatomic,readonly,strong) UIImageView *imageView; @property (nonatomic) BOOL reversesTitleShadowWhenHighlighted; @property (nonatomic) BOOL adjustsImageWhenHighlighted; @property (nonatomic) BOOL adjustsImageWhenDisabled; @@ -89,11 +74,9 @@ typedef enum { @property (nonatomic) UIEdgeInsets titleEdgeInsets; @property (nonatomic) UIEdgeInsets imageEdgeInsets; -@property (nonatomic, readonly, retain) NSString *currentTitle; -@property (nonatomic, readonly, retain) UIColor *currentTitleColor; -@property (nonatomic, readonly, retain) UIColor *currentTitleShadowColor; -@property (nonatomic, readonly, retain) UIImage *currentImage; -@property (nonatomic, readonly, retain) UIImage *currentBackgroundImage; - - +@property (nonatomic, readonly, strong) NSString *currentTitle; +@property (nonatomic, readonly, strong) UIColor *currentTitleColor; +@property (nonatomic, readonly, strong) UIColor *currentTitleShadowColor; +@property (nonatomic, readonly, strong) UIImage *currentImage; +@property (nonatomic, readonly, strong) UIImage *currentBackgroundImage; @end diff --git a/UIKit/Classes/UIButton.m b/UIKit/Classes/UIButton.m index 9cbb4892..707d83e8 100644 --- a/UIKit/Classes/UIButton.m +++ b/UIKit/Classes/UIButton.m @@ -41,11 +41,12 @@ static NSString *UIButtonContentTypeBackgroundImage = @"UIButtonContentTypeBackgroundImage"; static NSString *UIButtonContentTypeImage = @"UIButtonContentTypeImage"; -@implementation UIButton -@synthesize buttonType=_buttonType, titleLabel=_titleLabel, reversesTitleShadowWhenHighlighted=_reversesTitleShadowWhenHighlighted; -@synthesize adjustsImageWhenHighlighted=_adjustsImageWhenHighlighted, adjustsImageWhenDisabled=_adjustsImageWhenDisabled; -@synthesize showsTouchWhenHighlighted=_showsTouchWhenHighlighted, imageView=_imageView, contentEdgeInsets=_contentEdgeInsets; -@synthesize titleEdgeInsets=_titleEdgeInsets, imageEdgeInsets=_imageEdgeInsets; +@implementation UIButton { + UIImageView *_backgroundImageView; + NSMutableDictionary *_content; + UIImage *_adjustedHighlightImage; + UIImage *_adjustedDisabledImage; +} + (id)buttonWithType:(UIButtonType)buttonType { @@ -55,11 +56,11 @@ + (id)buttonWithType:(UIButtonType)buttonType case UIButtonTypeInfoLight: case UIButtonTypeInfoDark: case UIButtonTypeContactAdd: - return [[[UIRoundedRectButton alloc] init] autorelease]; + return [[UIRoundedRectButton alloc] init]; case UIButtonTypeCustom: default: - return [[[self alloc] init] autorelease]; + return [[self alloc] init]; } } @@ -87,16 +88,6 @@ - (id)initWithFrame:(CGRect)frame return self; } -- (void)dealloc -{ - [_content release]; - [_titleLabel release]; - [_imageView release]; - [_backgroundImageView release]; - [_adjustedHighlightImage release]; - [_adjustedDisabledImage release]; - [super dealloc]; -} - (NSString *)currentTitle { @@ -190,7 +181,7 @@ - (void)_setContent:(id)value forState:(UIControlState)state type:(NSString *)ty NSMutableDictionary *typeContent = [_content objectForKey:type]; if (!typeContent) { - typeContent = [[[NSMutableDictionary alloc] init] autorelease]; + typeContent = [[NSMutableDictionary alloc] init]; [_content setObject:typeContent forKey:type]; } @@ -226,8 +217,6 @@ - (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state - (void)setImage:(UIImage *)image forState:(UIControlState)state { - [_adjustedHighlightImage release]; - [_adjustedDisabledImage release]; _adjustedDisabledImage = _adjustedHighlightImage = nil; [self _setContent:image forState:state type:UIButtonContentTypeImage]; } diff --git a/UIKit/Classes/UIColor.h b/UIKit/Classes/UIColor.h index a3a9d51f..2d5ae67b 100644 --- a/UIKit/Classes/UIColor.h +++ b/UIKit/Classes/UIColor.h @@ -31,11 +31,7 @@ @class UIImage; -@interface UIColor : NSObject { -@private - id _representations; -} - +@interface UIColor : NSObject + (UIColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha; + (UIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha; + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; @@ -58,6 +54,9 @@ + (UIColor *)brownColor; + (UIColor *)clearColor; ++ (UIColor *)lightTextColor; ++ (UIColor *)darkTextColor; + - (id)initWithWhite:(CGFloat)white alpha:(CGFloat)alpha; - (id)initWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha; - (id)initWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; @@ -71,5 +70,4 @@ - (void)setStroke; @property (nonatomic, readonly) CGColorRef CGColor; - @end diff --git a/UIKit/Classes/UIColor.m b/UIKit/Classes/UIColor.m index 7dea338a..4e371402 100644 --- a/UIKit/Classes/UIColor.m +++ b/UIKit/Classes/UIColor.m @@ -49,13 +49,15 @@ static UIColor *PurpleColor = nil; static UIColor *BrownColor = nil; static UIColor *ClearColor = nil; +static UIColor *LightTextColor = nil; -@implementation UIColor +@implementation UIColor { + NSArray *_representations; +} - (id)initWithNSColor:(NSColor *)aColor { if (!aColor) { - [self release]; self = nil; } else { NSColor *c = [aColor colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]]; @@ -68,40 +70,35 @@ - (id)initWithNSColor:(NSColor *)aColor return self; } -- (void)dealloc -{ - [_representations release]; - [super dealloc]; -} + (id)colorWithNSColor:(NSColor *)c { - return [[[self alloc] initWithNSColor:c] autorelease]; + return [[self alloc] initWithNSColor:c]; } + (UIColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha { - return [[[self alloc] initWithWhite:white alpha:alpha] autorelease]; + return [[self alloc] initWithWhite:white alpha:alpha]; } + (UIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha { - return [[[self alloc] initWithHue:hue saturation:saturation brightness:brightness alpha:alpha] autorelease]; + return [[self alloc] initWithHue:hue saturation:saturation brightness:brightness alpha:alpha]; } + (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { - return [[[self alloc] initWithRed:red green:green blue:blue alpha:alpha] autorelease]; + return [[self alloc] initWithRed:red green:green blue:blue alpha:alpha]; } + (UIColor *)colorWithCGColor:(CGColorRef)ref { - return [[[self alloc] initWithCGColor:ref] autorelease]; + return [[self alloc] initWithCGColor:ref]; } + (UIColor *)colorWithPatternImage:(UIImage *)patternImage { - return [[[self alloc] initWithPatternImage:patternImage] autorelease]; + return [[self alloc] initWithPatternImage:patternImage]; } + (UIColor *)blackColor { return BlackColor ?: (BlackColor = [[self alloc] initWithNSColor:[NSColor blackColor]]); } @@ -119,6 +116,8 @@ + (UIColor *)orangeColor { return OrangeColor ?: (OrangeColor = [[self alloc] i + (UIColor *)purpleColor { return PurpleColor ?: (PurpleColor = [[self alloc] initWithNSColor:[NSColor purpleColor]]); } + (UIColor *)brownColor { return BrownColor ?: (BrownColor = [[self alloc] initWithNSColor:[NSColor brownColor]]); } + (UIColor *)clearColor { return ClearColor ?: (ClearColor = [[self alloc] initWithNSColor:[NSColor clearColor]]); } ++ (UIColor *)lightTextColor { return LightTextColor ?: (LightTextColor = [[self alloc] initWithWhite:1 alpha:0.6]); } ++ (UIColor *)darkTextColor { return [self blackColor]; } - (id)initWithWhite:(CGFloat)white alpha:(CGFloat)alpha { @@ -138,7 +137,6 @@ - (id)initWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CG - (id)_initWithRepresentations:(NSArray *)reps { if ([reps count] == 0) { - [self release]; self = nil; } else if ((self=[super init])) { _representations = [reps copy]; @@ -148,7 +146,7 @@ - (id)_initWithRepresentations:(NSArray *)reps - (id)initWithCGColor:(CGColorRef)ref { - return [self _initWithRepresentations:[NSArray arrayWithObjects:[[[UIColorRep alloc] initWithCGColor:ref] autorelease], nil]]; + return [self _initWithRepresentations:[NSArray arrayWithObjects:[[UIColorRep alloc] initWithCGColor:ref], nil]]; } - (id)initWithPatternImage:(UIImage *)patternImage @@ -157,7 +155,7 @@ - (id)initWithPatternImage:(UIImage *)patternImage NSMutableArray *colorReps = [NSMutableArray arrayWithCapacity:[imageReps count]]; for (UIImageRep *imageRep in imageReps) { - [colorReps addObject:[[[UIColorRep alloc] initWithPatternImageRepresentation:imageRep] autorelease]]; + [colorReps addObject:[[UIColorRep alloc] initWithPatternImageRepresentation:imageRep]]; } return [self _initWithRepresentations:colorReps]; @@ -227,7 +225,6 @@ - (NSColor *)NSColor const NSInteger numberOfComponents = CGColorGetNumberOfComponents(color); const CGFloat *components = CGColorGetComponents(color); NSColor *theColor = [NSColor colorWithColorSpace:colorSpace components:components count:numberOfComponents]; - [colorSpace release]; return theColor; } @@ -239,7 +236,7 @@ - (NSString *)description // Apple doesn't actually define UIDeviceRGBColorSpace or any of the other responses anywhere public, // so there isn't any easy way to emulate it. CGColorSpaceRef colorSpaceRef = CGColorGetColorSpace(self.CGColor); - NSString *colorSpace = [NSString stringWithFormat:@"%@", [(NSString *)CGColorSpaceCopyName(colorSpaceRef) autorelease]]; + NSString *colorSpace = [NSString stringWithFormat:@"%@", (NSString *)CFBridgingRelease(CGColorSpaceCopyName(colorSpaceRef))]; const size_t numberOfComponents = CGColorGetNumberOfComponents(self.CGColor); const CGFloat *components = CGColorGetComponents(self.CGColor); diff --git a/UIKit/Classes/UIColorRep.h b/UIKit/Classes/UIColorRep.h index 9251c70c..205b4f91 100644 --- a/UIKit/Classes/UIColorRep.h +++ b/UIKit/Classes/UIColorRep.h @@ -31,10 +31,7 @@ @class UIImageRep; -@interface UIColorRep : NSObject { - CGColorRef _CGColor; - UIImageRep *_patternImageRep; -} +@interface UIColorRep : NSObject - (id)initWithPatternImageRepresentation:(UIImageRep *)patternImageRep; - (id)initWithCGColor:(CGColorRef)color; diff --git a/UIKit/Classes/UIColorRep.m b/UIKit/Classes/UIColorRep.m index 6d0d4b9b..80d9dd21 100644 --- a/UIKit/Classes/UIColorRep.m +++ b/UIKit/Classes/UIColorRep.m @@ -35,7 +35,7 @@ static void drawPatternImage(void *info, CGContextRef ctx) { - UIImageRep *rep = [(UIColorRep *)info patternImageRep]; + UIImageRep *rep = [(__bridge UIColorRep *)info patternImageRep]; UIGraphicsPushContext(ctx); CGContextSaveGState(ctx); @@ -63,16 +63,16 @@ static void drawPatternImage(void *info, CGContextRef ctx) UIGraphicsPopContext(); } -@implementation UIColorRep -@synthesize patternImageRep = _patternImageRep; +@implementation UIColorRep { + CGColorRef _CGColor; +} - (id)initWithPatternImageRepresentation:(UIImageRep *)patternImageRep { if (!patternImageRep) { - [self release]; self = nil; } else if ((self=[super init])) { - _patternImageRep = [patternImageRep retain]; + _patternImageRep = patternImageRep; } return self; } @@ -80,7 +80,6 @@ - (id)initWithPatternImageRepresentation:(UIImageRep *)patternImageRep - (id)initWithCGColor:(CGColorRef)color { if (!color) { - [self release]; self = nil; } else if ((self=[super init])) { _CGColor = CGColorRetain(color); @@ -90,9 +89,7 @@ - (id)initWithCGColor:(CGColorRef)color - (void)dealloc { - [_patternImageRep release]; CGColorRelease(_CGColor); - [super dealloc]; } - (CGColorRef)CGColor @@ -104,7 +101,7 @@ - (CGColorRef)CGColor const CGAffineTransform t = CGAffineTransformMakeScale(scaler, scaler); static const CGPatternCallbacks callbacks = {0, &drawPatternImage, NULL}; - CGPatternRef pattern = CGPatternCreate ((void *)self, + CGPatternRef pattern = CGPatternCreate ((__bridge void *)self, CGRectMake (0, 0, imageSize.width, imageSize.height), t, imageSize.width, diff --git a/UIKit/Classes/UIControl.h b/UIKit/Classes/UIControl.h index eed037b7..eb4eb52b 100644 --- a/UIKit/Classes/UIControl.h +++ b/UIKit/Classes/UIControl.h @@ -29,7 +29,7 @@ #import "UIView.h" -enum { +typedef NS_OPTIONS(NSUInteger, UIControlEvents) { UIControlEventTouchDown = 1 << 0, UIControlEventTouchDownRepeat = 1 << 1, UIControlEventTouchDragInside = 1 << 2, @@ -54,9 +54,7 @@ enum { UIControlEventAllEvents = 0xFFFFFFFF }; -typedef NSUInteger UIControlEvents; - -enum { +typedef NS_OPTIONS(NSUInteger, UIControlState) { UIControlStateNormal = 0, UIControlStateHighlighted = 1 << 0, UIControlStateDisabled = 1 << 1, @@ -65,34 +63,23 @@ enum { UIControlStateReserved = 0xFF000000 }; -typedef NSUInteger UIControlState; - -typedef enum { +typedef NS_ENUM(NSInteger, UIControlContentHorizontalAlignment) { UIControlContentHorizontalAlignmentCenter = 0, UIControlContentHorizontalAlignmentLeft = 1, UIControlContentHorizontalAlignmentRight = 2, UIControlContentHorizontalAlignmentFill = 3, -} UIControlContentHorizontalAlignment; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIControlContentVerticalAlignment) { UIControlContentVerticalAlignmentCenter = 0, UIControlContentVerticalAlignmentTop = 1, UIControlContentVerticalAlignmentBottom = 2, UIControlContentVerticalAlignmentFill = 3, -} UIControlContentVerticalAlignment; +}; -@interface UIControl : UIView { -@protected - NSMutableArray *_registeredActions; - BOOL _tracking; - BOOL _touchInside; - BOOL _enabled; - BOOL _selected; - BOOL _highlighted; - UIControlContentHorizontalAlignment _contentHorizontalAlignment; - UIControlContentVerticalAlignment _contentVerticalAlignment; -} +@class UITouch; +@interface UIControl : UIView - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents; - (void)removeTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents; - (NSArray *)actionsForTarget:(id)target forControlEvent:(UIControlEvents)controlEvent; @@ -117,5 +104,4 @@ typedef enum { @property (nonatomic) UIControlContentHorizontalAlignment contentHorizontalAlignment; @property (nonatomic) UIControlContentVerticalAlignment contentVerticalAlignment; - @end diff --git a/UIKit/Classes/UIControl.m b/UIKit/Classes/UIControl.m index 02431f6a..0a10dfbe 100644 --- a/UIKit/Classes/UIControl.m +++ b/UIKit/Classes/UIControl.m @@ -33,9 +33,9 @@ #import "UIApplication.h" #import "UIControlAction.h" -@implementation UIControl -@synthesize tracking=_tracking, touchInside=_touchInside, selected=_selected, enabled=_enabled, highlighted=_highlighted; -@synthesize contentHorizontalAlignment=_contentHorizontalAlignment, contentVerticalAlignment=_contentVerticalAlignment; +@implementation UIControl { + NSMutableArray *_registeredActions; +} - (id)initWithFrame:(CGRect)frame { @@ -48,11 +48,6 @@ - (id)initWithFrame:(CGRect)frame return self; } -- (void)dealloc -{ - [_registeredActions release]; - [super dealloc]; -} - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents { @@ -61,7 +56,6 @@ - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvent controlAction.action = action; controlAction.controlEvents = controlEvents; [_registeredActions addObject:controlAction]; - [controlAction release]; } - (void)removeTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents @@ -75,7 +69,6 @@ - (void)removeTarget:(id)target action:(SEL)action forControlEvents:(UIControlEv } [_registeredActions removeObjectsInArray:discard]; - [discard release]; } - (NSArray *)actionsForTarget:(id)target forControlEvent:(UIControlEvents)controlEvent @@ -89,10 +82,9 @@ - (NSArray *)actionsForTarget:(id)target forControlEvent:(UIControlEvents)contro } if ([actions count] == 0) { - [actions release]; return nil; } else { - return [actions autorelease]; + return actions; } } diff --git a/UIKit/Classes/UIControlAction.h b/UIKit/Classes/UIControlAction.h index 207ec53e..4358720d 100644 --- a/UIKit/Classes/UIControlAction.h +++ b/UIKit/Classes/UIControlAction.h @@ -30,10 +30,6 @@ #import "UIAction.h" #import "UIControl.h" -@interface UIControlAction : UIAction { - UIControlEvents _controlEvents; -} - +@interface UIControlAction : UIAction @property (nonatomic, assign) UIControlEvents controlEvents; - @end diff --git a/UIKit/Classes/UIControlAction.m b/UIKit/Classes/UIControlAction.m index a8e445fb..bcb514a6 100644 --- a/UIKit/Classes/UIControlAction.m +++ b/UIKit/Classes/UIControlAction.m @@ -30,6 +30,4 @@ #import "UIControlAction.h" @implementation UIControlAction -@synthesize controlEvents=_controlEvents; - @end diff --git a/UIKit/Classes/UICustomNSClipView.h b/UIKit/Classes/UICustomNSClipView.h index 56b2175b..1b09df4f 100644 --- a/UIKit/Classes/UICustomNSClipView.h +++ b/UIKit/Classes/UICustomNSClipView.h @@ -40,18 +40,13 @@ - (BOOL)clipViewShouldScroll; @end -@interface UICustomNSClipView : NSClipView { - CALayer *parentLayer; - id behaviorDelegate; -} - +@interface UICustomNSClipView : NSClipView - (id)initWithFrame:(NSRect)frame; // A layer parent is just a layer that UICustonNSClipView will attempt to always remain a sublayer of. // Circumventing AppKit for fun and profit! // The hitDelegate is for faking out the NSView's usual hitTest: checks to handle cases where UIViews are above // the UIView that's displaying this layer. -@property (nonatomic, assign) CALayer *parentLayer; +@property (nonatomic, weak) CALayer *parentLayer; @property (nonatomic, assign) id behaviorDelegate; - @end diff --git a/UIKit/Classes/UICustomNSClipView.m b/UIKit/Classes/UICustomNSClipView.m index e18137d0..f879504f 100644 --- a/UIKit/Classes/UICustomNSClipView.m +++ b/UIKit/Classes/UICustomNSClipView.m @@ -33,7 +33,6 @@ #import @implementation UICustomNSClipView -@synthesize parentLayer, behaviorDelegate; - (id)initWithFrame:(NSRect)frame { @@ -46,7 +45,7 @@ - (id)initWithFrame:(NSRect)frame - (void)scrollWheel:(NSEvent *)event { - if ([behaviorDelegate clipViewShouldScroll]) { + if ([self.behaviorDelegate clipViewShouldScroll]) { NSPoint offset = [self bounds].origin; offset.x += [event deltaX]; offset.y -= [event deltaY]; @@ -60,19 +59,18 @@ - (void)scrollWheel:(NSEvent *)event - (void)fixupTheLayer { - if ([self superview] && parentLayer) { + if ([self superview] && self.parentLayer) { [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue - forKey:kCATransactionDisableActions]; + [CATransaction setAnimationDuration:0]; CALayer *layer = [self layer]; - if (parentLayer != layer.superlayer) { - [parentLayer addSublayer:layer]; + if (self.parentLayer != layer.superlayer) { + [self.parentLayer addSublayer:layer]; } - if (!CGRectEqualToRect(layer.frame, parentLayer.bounds)) { - layer.frame = parentLayer.bounds; + if (!CGRectEqualToRect(layer.frame, self.parentLayer.bounds)) { + layer.frame = self.parentLayer.bounds; } [CATransaction commit]; @@ -107,12 +105,12 @@ - (NSView *)hitTest:(NSPoint)aPoint { NSView *hit = [super hitTest:aPoint]; - if (hit && behaviorDelegate) { + if (hit && self.behaviorDelegate) { // call out to the text layer via a delegate or something and ask if this point should be considered a hit or not. // if not, then we set hit to nil, otherwise we return it like normal. // the purpose of this is to make the NSView act invisible/hidden to clicks when it's visually behind other UIViews. // super tricky, eh? - if (![behaviorDelegate hitTestForClipViewPoint:aPoint]) { + if (![self.behaviorDelegate hitTestForClipViewPoint:aPoint]) { hit = nil; } } diff --git a/UIKit/Classes/UICustomNSTextView.h b/UIKit/Classes/UICustomNSTextView.h index d8f6b749..76700fd7 100644 --- a/UIKit/Classes/UICustomNSTextView.h +++ b/UIKit/Classes/UICustomNSTextView.h @@ -37,10 +37,7 @@ - (BOOL)textView:(UICustomNSTextView *)textView shouldAcceptKeyDown:(NSEvent *)event; @end -@interface UICustomNSTextView: NSTextView { - BOOL secureTextEntry; - BOOL isBecomingFirstResponder; -} +@interface UICustomNSTextView: NSTextView - (id)initWithFrame:(NSRect)frame secureTextEntry:(BOOL)isSecure isField:(BOOL)isField; - (void)setSecureTextEntry:(BOOL)isSecure; diff --git a/UIKit/Classes/UICustomNSTextView.m b/UIKit/Classes/UICustomNSTextView.m index cc3165ba..8fef4c3b 100644 --- a/UIKit/Classes/UICustomNSTextView.m +++ b/UIKit/Classes/UICustomNSTextView.m @@ -44,7 +44,10 @@ @interface UICustomNSTextView () @end -@implementation UICustomNSTextView +@implementation UICustomNSTextView { + BOOL _secureTextEntry; + BOOL _isBecomingFirstResponder; +} - (id)initWithFrame:(NSRect)frame secureTextEntry:(BOOL)isSecure isField:(BOOL)isField { @@ -66,11 +69,13 @@ - (id)initWithFrame:(NSRect)frame secureTextEntry:(BOOL)isSecure isField:(BOOL)i [self setVerticallyResizable:NO]; [[self textContainer] setWidthTracksTextView:NO]; [[self textContainer] setContainerSize:maxSize]; + [self setTextContainerInset:NSMakeSize(0, 0)]; } else { [self setFieldEditor:NO]; [self setHorizontallyResizable:NO]; [self setVerticallyResizable:YES]; [self setAutoresizingMask:NSViewWidthSizable]; + [self setTextContainerInset:NSMakeSize(3, 8)]; } [self setMaxSize:maxSize]; @@ -81,7 +86,9 @@ - (id)initWithFrame:(NSRect)frame secureTextEntry:(BOOL)isSecure isField:(BOOL)i [self setAllowsImageEditing:NO]; [self setDisplaysLinkToolTips:NO]; [self setAutomaticDataDetectionEnabled:NO]; - [self setSecureTextEntry:isSecure]; + + // same color as iOS + [self setInsertionPointColor:[NSColor colorWithCalibratedRed:62/255.f green:100/255.f blue:243/255.f alpha:1]]; [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; @@ -96,7 +103,7 @@ - (void)updateStyles NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; [style setParagraphStyle:[NSParagraphStyle defaultParagraphStyle]]; - if (secureTextEntry) { + if (_secureTextEntry) { // being all super-paranoid here... [self setAutomaticQuoteSubstitutionEnabled:NO]; [self setGrammarCheckingEnabled:NO]; @@ -107,7 +114,7 @@ - (void)updateStyles [self setSmartInsertDeleteEnabled:NO]; [self setUsesFindPanel:NO]; [self setAllowsUndo:NO]; - [[self layoutManager] setGlyphGenerator:[[[UIBulletGlyphGenerator alloc] init] autorelease]]; + [[self layoutManager] setGlyphGenerator:[[UIBulletGlyphGenerator alloc] init]]; [style setLineBreakMode:NSLineBreakByCharWrapping]; } else { [self setAllowsUndo:YES]; @@ -122,18 +129,17 @@ - (void)updateStyles } [self setDefaultParagraphStyle:style]; - [style release]; } - (void)setSecureTextEntry:(BOOL)isSecure { - secureTextEntry = isSecure; + _secureTextEntry = isSecure; [self updateStyles]; } - (BOOL)validateMenuItem:(NSMenuItem *)menuItem { - if (secureTextEntry && ([menuItem action] == @selector(copy:) || [menuItem action] == @selector(cut:))) { + if (_secureTextEntry && ([menuItem action] == @selector(copy:) || [menuItem action] == @selector(cut:))) { return NO; // don't allow copying/cutting out from a secure field } else { return [super validateMenuItem:menuItem]; @@ -142,7 +148,7 @@ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem - (NSSelectionGranularity)selectionGranularity { - if (secureTextEntry) { + if (_secureTextEntry) { return NSSelectByCharacter; // trying to avoid the secure one giving any hints about what's under it. :/ } else { return [super selectionGranularity]; @@ -152,14 +158,14 @@ - (NSSelectionGranularity)selectionGranularity - (void)startSpeaking:(id)sender { // only allow speaking if it's not secure - if (!secureTextEntry) { + if (!_secureTextEntry) { [super startSpeaking:sender]; } } - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType { - if (secureTextEntry) { + if (_secureTextEntry) { return nil; } else { return [super validRequestorForSendType:sendType returnType:returnType]; @@ -173,8 +179,8 @@ - (NSMenu *)menuForEvent:(NSEvent *)theEvent // screw it.. why not just remove everything from the context menu if it's a secure field? :) // it's possible that various key combos could still allow things like searching in spotlight which // then would revel the actual value of the password field, but at least those are sorta obscure :) - if (secureTextEntry) { - NSArray *items = [[[menu itemArray] copy] autorelease]; + if (_secureTextEntry) { + NSArray *items = [[menu itemArray] copy]; for (NSMenuItem *item in items) { if ([item action] != @selector(paste:)) { [menu removeItem:item]; @@ -198,9 +204,9 @@ - (void)setDelegate:(id)d - (BOOL)becomeFirstResponder { - isBecomingFirstResponder = YES; + _isBecomingFirstResponder = YES; BOOL result = [[self delegate] textViewBecomeFirstResponder:self]; - isBecomingFirstResponder = NO; + _isBecomingFirstResponder = NO; return result; } @@ -211,7 +217,7 @@ - (BOOL)reallyBecomeFirstResponder - (BOOL)resignFirstResponder { - if(isBecomingFirstResponder) return NO; + if(_isBecomingFirstResponder) return NO; return [[self delegate] textViewResignFirstResponder:self]; } diff --git a/UIKit/Classes/UIDataDetectors.h b/UIKit/Classes/UIDataDetectors.h index 1e3f895d..8d15acef 100644 --- a/UIKit/Classes/UIDataDetectors.h +++ b/UIKit/Classes/UIDataDetectors.h @@ -29,11 +29,10 @@ #import -enum { +typedef NS_OPTIONS(NSUInteger, UIDataDetectorTypes) { UIDataDetectorTypePhoneNumber = 1 << 0, UIDataDetectorTypeLink = 1 << 1, UIDataDetectorTypeNone = 0, UIDataDetectorTypeAll = NSUIntegerMax }; -typedef NSUInteger UIDataDetectorTypes; diff --git a/UIKit/Classes/UIDatePicker.h b/UIKit/Classes/UIDatePicker.h index e6a3cfa7..e0f26d0f 100644 --- a/UIKit/Classes/UIDatePicker.h +++ b/UIKit/Classes/UIDatePicker.h @@ -31,39 +31,21 @@ #import #import "UIControl.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIDatePickerMode) { UIDatePickerModeTime, UIDatePickerModeDate, UIDatePickerModeDateAndTime, UIDatePickerModeCountDownTimer -} UIDatePickerMode; +}; @interface UIDatePicker : UIControl -{ - @private - NSCalendar *_calendar; - NSDate *_date; - NSLocale *_locale; - NSTimeZone *_timeZone; - - UIDatePickerMode _datePickerMode; - - NSDate *_minimumDate; - NSDate *_maximumDate; - NSInteger _minuteInterval; - NSTimeInterval _countDownDuration; -} - -@property (nonatomic, retain) NSCalendar *calendar; -@property (nonatomic, retain) NSDate *date; -@property (nonatomic, retain) NSLocale *locale; -@property (nonatomic, retain) NSTimeZone *timeZone; - +@property (nonatomic, strong) NSCalendar *calendar; +@property (nonatomic, strong) NSDate *date; +@property (nonatomic, strong) NSLocale *locale; +@property (nonatomic, strong) NSTimeZone *timeZone; @property (nonatomic, assign) UIDatePickerMode datePickerMode; - -@property (nonatomic, retain) NSDate *minimumDate; -@property (nonatomic, retain) NSDate *maximumDate; +@property (nonatomic, strong) NSDate *minimumDate; +@property (nonatomic, strong) NSDate *maximumDate; @property (nonatomic, assign) NSInteger minuteInterval; @property (nonatomic, assign) NSTimeInterval countDownDuration; - @end diff --git a/UIKit/Classes/UIDatePicker.m b/UIKit/Classes/UIDatePicker.m index c8a12ef6..1f83f599 100644 --- a/UIKit/Classes/UIDatePicker.m +++ b/UIKit/Classes/UIDatePicker.m @@ -29,28 +29,5 @@ #import "UIDatePicker.h" - @implementation UIDatePicker - -@synthesize calendar = _calendar; -@synthesize date = _date; -@synthesize locale = _locale; -@synthesize timeZone = _timeZone; -@synthesize datePickerMode = _datePickerMode; -@synthesize minimumDate = _minimumDate; -@synthesize maximumDate = _maximumDate; -@synthesize minuteInterval = _minuteInterval; -@synthesize countDownDuration = _countDownDuration; - -- (void) dealloc -{ - [_calendar release]; - [_date release]; - [_locale release]; - [_timeZone release]; - [_minimumDate release]; - [_maximumDate release]; - [super dealloc]; -} - @end diff --git a/UIKit/Classes/UIDevice.h b/UIKit/Classes/UIDevice.h index c2ce9ea3..d1d035a2 100644 --- a/UIKit/Classes/UIDevice.h +++ b/UIKit/Classes/UIDevice.h @@ -31,7 +31,7 @@ extern NSString *const UIDeviceOrientationDidChangeNotification; -typedef enum { +typedef NS_ENUM(NSInteger, UIDeviceOrientation) { UIDeviceOrientationUnknown, UIDeviceOrientationPortrait, UIDeviceOrientationPortraitUpsideDown, @@ -39,13 +39,13 @@ typedef enum { UIDeviceOrientationLandscapeRight, UIDeviceOrientationFaceUp, UIDeviceOrientationFaceDown -} UIDeviceOrientation; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIUserInterfaceIdiom) { UIUserInterfaceIdiomPhone, UIUserInterfaceIdiomPad, UIUserInterfaceIdiomDesktop, -} UIUserInterfaceIdiom; +}; #define UI_USER_INTERFACE_IDIOM() \ ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? \ @@ -60,21 +60,18 @@ typedef enum { ((orientation) == UIDeviceOrientationLandscapeLeft || \ (orientation) == UIDeviceOrientationLandscapeRight) -@interface UIDevice : NSObject { -} - +@interface UIDevice : NSObject + (UIDevice *)currentDevice; -@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,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 - - (void)beginGeneratingDeviceOrientationNotifications; // no effect - (void)endGeneratingDeviceOrientationNotifications; // no effect +@property (nonatomic, readonly, strong) NSString *name; +@property (nonatomic, assign) UIUserInterfaceIdiom userInterfaceIdiom; // default is UIUserInterfaceIdiomDesktop (obviously real UIKit doesn't allow setting this!) +@property (nonatomic, readonly) UIDeviceOrientation orientation; // always returns UIDeviceOrientationPortrait +@property (nonatomic, readonly,getter=isMultitaskingSupported) BOOL multitaskingSupported; // always returns YES +@property (nonatomic, readonly, strong) NSString *systemName; +@property (nonatomic, readonly, strong) NSString *systemVersion; +@property (nonatomic, readonly, strong) NSString *model; +@property (nonatomic, readonly, getter=isGeneratingDeviceOrientationNotifications) BOOL generatesDeviceOrientationNotifications; // aways returns NO @end diff --git a/UIKit/Classes/UIDevice.m b/UIKit/Classes/UIDevice.m index a5622709..76e0db75 100644 --- a/UIKit/Classes/UIDevice.m +++ b/UIKit/Classes/UIDevice.m @@ -49,14 +49,17 @@ + (UIDevice *)currentDevice return theDevice; } -- (UIUserInterfaceIdiom)userInterfaceIdiom +- (id)init { - return UIUserInterfaceIdiomDesktop; + if ((self=[super init])) { + _userInterfaceIdiom = UIUserInterfaceIdiomDesktop; + } + return self; } - (NSString *)name { - return [(__bridge NSString *)SCDynamicStoreCopyComputerName(NULL,NULL) autorelease]; + return (__bridge_transfer NSString *)SCDynamicStoreCopyComputerName(NULL,NULL); } - (UIDeviceOrientation)orientation diff --git a/UIKit/Classes/UIEvent.h b/UIKit/Classes/UIEvent.h index 97665912..8a2fb180 100644 --- a/UIKit/Classes/UIEvent.h +++ b/UIKit/Classes/UIEvent.h @@ -29,35 +29,29 @@ #import -typedef enum { +typedef NS_ENUM(NSInteger, UIEventType) { UIEventTypeTouches, UIEventTypeMotion, - UIEventTypeKeyPress // AppKitIntegration -} UIEventType; + + // nonstandard + UIEventTypeKeyboard, + UIEventTypeAction +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIEventSubtype) { UIEventSubtypeNone = 0, UIEventSubtypeMotionShake = 1, -} UIEventSubtype; +}; -@class UITouch, UIWindow, UIView, UIGestureRecognizer; - -@interface UIEvent : NSObject { -@private - UIEventType _type; - UITouch *_touch; - NSTimeInterval _timestamp; - BOOL _unhandledKeyPressEvent; -} - -@property (nonatomic, readonly) NSTimeInterval timestamp; +@class UIWindow, UIView, UIGestureRecognizer; +@interface UIEvent : NSObject - (NSSet *)allTouches; - (NSSet *)touchesForView:(UIView *)view; - (NSSet *)touchesForWindow:(UIWindow *)window; - (NSSet *)touchesForGestureRecognizer:(UIGestureRecognizer *)gesture; +@property (nonatomic, readonly) NSTimeInterval timestamp; @property (nonatomic, readonly) UIEventType type; @property (nonatomic, readonly) UIEventSubtype subtype; - @end diff --git a/UIKit/Classes/UIEvent.m b/UIKit/Classes/UIEvent.m index cc2546e2..427b61aa 100644 --- a/UIKit/Classes/UIEvent.m +++ b/UIKit/Classes/UIEvent.m @@ -27,55 +27,22 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIEvent+UIPrivate.h" +#import "UIEvent.h" #import "UITouch.h" @implementation UIEvent -@synthesize timestamp=_timestamp, type=_type; -- (id)initWithEventType:(UIEventType)type +- (id)init { if ((self=[super init])) { - _type = type; - _unhandledKeyPressEvent = NO; + _timestamp = [NSDate timeIntervalSinceReferenceDate]; } return self; } -- (void)dealloc -{ - [_touch release]; - [super dealloc]; -} - -- (void)_setTouch:(UITouch *)t -{ - if (_touch != t) { - [_touch release]; - _touch = [t retain]; - } -} - -- (void)_setTimestamp:(NSTimeInterval)timestamp -{ - _timestamp = timestamp; -} - -// this is stupid hack so that keyboard events can fall to AppKit's next responder if nothing within UIKit handles it -// I couldn't come up with a better way at the time. meh. -- (void)_setUnhandledKeyPressEvent -{ - _unhandledKeyPressEvent = YES; -} - -- (BOOL)_isUnhandledKeyPressEvent -{ - return _unhandledKeyPressEvent; -} - - (NSSet *)allTouches { - return [NSSet setWithObject:_touch]; + return nil; } - (NSSet *)touchesForView:(UIView *)view @@ -111,6 +78,11 @@ - (NSSet *)touchesForGestureRecognizer:(UIGestureRecognizer *)gesture return touches; } +- (UIEventType)type +{ + return -1; +} + - (UIEventSubtype)subtype { return UIEventSubtypeNone; diff --git a/UIKit/Classes/UIFont.h b/UIKit/Classes/UIFont.h index 80d6ee9a..43393ed5 100644 --- a/UIKit/Classes/UIFont.h +++ b/UIKit/Classes/UIFont.h @@ -43,14 +43,12 @@ - (UIFont *)fontWithSize:(CGFloat)fontSize; -@property (nonatomic, readonly, retain) NSString *fontName; - +@property (nonatomic, readonly, strong) NSString *fontName; @property (nonatomic, readonly) CGFloat ascender; @property (nonatomic, readonly) CGFloat descender; @property (nonatomic, readonly) CGFloat lineHeight; @property (nonatomic, readonly) CGFloat pointSize; @property (nonatomic, readonly) CGFloat xHeight; @property (nonatomic, readonly) CGFloat capHeight; -@property (nonatomic, readonly, retain) NSString *familyName; - +@property (nonatomic, readonly, strong) NSString *familyName; @end diff --git a/UIKit/Classes/UIFont.m b/UIKit/Classes/UIFont.m index dcbab16e..a7628bf5 100644 --- a/UIKit/Classes/UIFont.m +++ b/UIKit/Classes/UIFont.m @@ -37,13 +37,11 @@ @implementation UIFont + (void)setSystemFontName:(NSString *)aName { - [UIFontSystemFontName release]; UIFontSystemFontName = [aName copy]; } + (void)setBoldSystemFontName:(NSString *)aName { - [UIFontBoldSystemFontName release]; UIFontBoldSystemFontName = [aName copy]; } @@ -51,7 +49,7 @@ + (UIFont *)_fontWithCTFont:(CTFontRef)aFont { UIFont *theFont = [[UIFont alloc] init]; theFont->_font = CFRetain(aFont); - return [theFont autorelease]; + return theFont; } + (UIFont *)fontWithNSFont:(NSFont *)aFont @@ -140,12 +138,11 @@ + (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize - (void)dealloc { if (_font) CFRelease(_font); - [super dealloc]; } - (NSString *)fontName { - return [(NSString *)CTFontCopyFullName(_font) autorelease]; + return (NSString *)CFBridgingRelease(CTFontCopyPostScriptName(_font)); } - (CGFloat)ascender @@ -184,14 +181,14 @@ - (CGFloat)lineHeight - (NSString *)familyName { - return [(NSString *)CTFontCopyFamilyName(_font) autorelease]; + return (NSString *)CFBridgingRelease(CTFontCopyFamilyName(_font)); } - (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/UIGestureRecognizer+UIPrivate.h b/UIKit/Classes/UIGestureRecognizer+UIPrivate.h index 3e2b5ff9..fb57e1d0 100644 --- a/UIKit/Classes/UIGestureRecognizer+UIPrivate.h +++ b/UIKit/Classes/UIGestureRecognizer+UIPrivate.h @@ -29,7 +29,13 @@ #import "UIGestureRecognizer.h" +@class UITouchEvent; + @interface UIGestureRecognizer (UIPrivate) - (void)_setView:(UIView *)v; -- (void)_recognizeTouches:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)_abort; + +- (void)_beginTrackingTouch:(UITouch *)touch withEvent:(UITouchEvent *)event; +- (void)_continueTrackingWithEvent:(UITouchEvent *)event; +- (void)_endTrackingTouch:(UITouch *)touch withEvent:(UITouchEvent *)event; @end diff --git a/UIKit/Classes/UIGestureRecognizer.h b/UIKit/Classes/UIGestureRecognizer.h index 7dbf1f3d..84d49d6b 100644 --- a/UIKit/Classes/UIGestureRecognizer.h +++ b/UIKit/Classes/UIGestureRecognizer.h @@ -29,7 +29,7 @@ #import -typedef enum { +typedef NS_ENUM(NSInteger, UIGestureRecognizerState) { UIGestureRecognizerStatePossible, UIGestureRecognizerStateBegan, UIGestureRecognizerStateChanged, @@ -37,7 +37,7 @@ typedef enum { UIGestureRecognizerStateCancelled, UIGestureRecognizerStateFailed, UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded -} UIGestureRecognizerState; +}; @class UIView, UIGestureRecognizer, UITouch, UIEvent; @@ -48,25 +48,7 @@ typedef enum { - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; @end -@interface UIGestureRecognizer : NSObject { -@private - __unsafe_unretained id _delegate; - BOOL _delaysTouchesBegan; - BOOL _delaysTouchesEnded; - BOOL _cancelsTouchesInView; - BOOL _enabled; - UIGestureRecognizerState _state; - UIView *_view; - NSMutableArray *_registeredActions; - NSMutableArray *_trackingTouches; - - struct { - unsigned shouldBegin : 1; - unsigned shouldReceiveTouch : 1; - unsigned shouldRecognizeSimultaneouslyWithGestureRecognizer : 1; - } _delegateHas; -} - +@interface UIGestureRecognizer : NSObject - (id)initWithTarget:(id)target action:(SEL)action; - (void)addTarget:(id)target action:(SEL)action; @@ -84,5 +66,4 @@ typedef enum { @property (nonatomic, getter=isEnabled) BOOL enabled; @property (nonatomic, readonly) UIGestureRecognizerState state; @property (nonatomic, readonly) UIView *view; - @end diff --git a/UIKit/Classes/UIGestureRecognizer.m b/UIKit/Classes/UIGestureRecognizer.m index 37dc8f87..25a82102 100644 --- a/UIKit/Classes/UIGestureRecognizer.m +++ b/UIKit/Classes/UIGestureRecognizer.m @@ -32,10 +32,19 @@ #import "UITouch+UIPrivate.h" #import "UIAction.h" #import "UIApplication.h" +#import "UITouchEvent.h" -@implementation UIGestureRecognizer -@synthesize delegate=_delegate, delaysTouchesBegan=_delaysTouchesBegan, delaysTouchesEnded=_delaysTouchesEnded, cancelsTouchesInView=_cancelsTouchesInView; -@synthesize state=_state, enabled=_enabled, view=_view; +@implementation UIGestureRecognizer { + NSMutableArray *_registeredActions; + NSMutableArray *_trackingTouches; + __unsafe_unretained UIView *_view; + + struct { + unsigned shouldBegin : 1; + unsigned shouldReceiveTouch : 1; + unsigned shouldRecognizeSimultaneouslyWithGestureRecognizer : 1; + } _delegateHas; +} - (id)initWithTarget:(id)target action:(SEL)action { @@ -54,17 +63,12 @@ - (id)initWithTarget:(id)target action:(SEL)action return self; } -- (void)dealloc -{ - [_registeredActions release]; - [_trackingTouches release]; - [super dealloc]; -} - - (void)_setView:(UIView *)v { - [self reset]; // not sure about this, but it kinda makes sense - _view = v; + if (v != _view) { + [self reset]; // not sure about this, but I think it makes sense + _view = v; + } } - (void)setDelegate:(id)aDelegate @@ -86,7 +90,6 @@ - (void)addTarget:(id)target action:(SEL)action actionRecord.target = target; actionRecord.action = action; [_registeredActions addObject:actionRecord]; - [actionRecord release]; } - (void)removeTarget:(id)target action:(SEL)action @@ -95,7 +98,6 @@ - (void)removeTarget:(id)target action:(SEL)action actionRecord.target = target; actionRecord.action = action; [_registeredActions removeObject:actionRecord]; - [actionRecord release]; } - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer @@ -138,25 +140,31 @@ - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView *)view - (void)setState:(UIGestureRecognizerState)state { + if (_delegateHas.shouldBegin && _state == UIGestureRecognizerStatePossible && (state == UIGestureRecognizerStateRecognized || state == UIGestureRecognizerStateBegan)) { + if (![_delegate gestureRecognizerShouldBegin:self]) { + state = UIGestureRecognizerStateFailed; + } + } + // the docs didn't say explicitly if these state transitions were verified, but I suspect they are. if anything, a check like this // should help debug things. it also helps me better understand the whole thing, so it's not a total waste of time :) - typedef struct { UIGestureRecognizerState fromState, toState; BOOL shouldNotify, shouldReset; } StateTransition; + typedef struct { UIGestureRecognizerState fromState, toState; BOOL shouldNotify; } StateTransition; #define NumberOfStateTransitions 9 static const StateTransition allowedTransitions[NumberOfStateTransitions] = { // discrete gestures - {UIGestureRecognizerStatePossible, UIGestureRecognizerStateRecognized, YES, YES}, - {UIGestureRecognizerStatePossible, UIGestureRecognizerStateFailed, NO, YES}, + {UIGestureRecognizerStatePossible, UIGestureRecognizerStateRecognized, YES}, + {UIGestureRecognizerStatePossible, UIGestureRecognizerStateFailed, NO}, // continuous gestures - {UIGestureRecognizerStatePossible, UIGestureRecognizerStateBegan, YES, NO }, - {UIGestureRecognizerStateBegan, UIGestureRecognizerStateChanged, YES, NO }, - {UIGestureRecognizerStateBegan, UIGestureRecognizerStateCancelled, YES, YES}, - {UIGestureRecognizerStateBegan, UIGestureRecognizerStateEnded, YES, YES}, - {UIGestureRecognizerStateChanged, UIGestureRecognizerStateChanged, YES, NO }, - {UIGestureRecognizerStateChanged, UIGestureRecognizerStateCancelled, YES, YES}, - {UIGestureRecognizerStateChanged, UIGestureRecognizerStateEnded, YES, YES} + {UIGestureRecognizerStatePossible, UIGestureRecognizerStateBegan, YES}, + {UIGestureRecognizerStateBegan, UIGestureRecognizerStateChanged, YES}, + {UIGestureRecognizerStateBegan, UIGestureRecognizerStateCancelled, YES}, + {UIGestureRecognizerStateBegan, UIGestureRecognizerStateEnded, YES}, + {UIGestureRecognizerStateChanged, UIGestureRecognizerStateChanged, YES}, + {UIGestureRecognizerStateChanged, UIGestureRecognizerStateCancelled, YES}, + {UIGestureRecognizerStateChanged, UIGestureRecognizerStateEnded, YES} }; const StateTransition *transition = NULL; @@ -168,7 +176,7 @@ - (void)setState:(UIGestureRecognizerState)state } } - NSAssert2((transition != NULL), @"invalid state transition from %d to %d", _state, state); + NSAssert2((transition != NULL), @"invalid state transition from %ld to %ld", _state, state); if (transition) { _state = transition->toState; @@ -178,22 +186,22 @@ - (void)setState:(UIGestureRecognizerState)state // docs mention that the action messages are sent on the next run loop, so we'll do that here. // note that this means that reset can't happen until the next run loop, either otherwise // the state property is going to be wrong when the action handler looks at it, so as a result - // I'm also delaying the reset call (if necessary) just below here. + // I'm also delaying the reset call (if necessary) below in -continueTrackingWithEvent: [actionRecord.target performSelector:actionRecord.action withObject:self afterDelay:0]; } } - - if (transition->shouldReset) { - // see note above about the delay - [self performSelector:@selector(reset) withObject:nil afterDelay:0]; - } } } - (void)reset { + // note - this is also supposed to ignore any currently tracked touches + // the touches themselves may not have gone away, so we don't just remove them from tracking, I think, + // but instead just mark them as ignored by this gesture until the touches eventually end themselves. + // in any case, this isn't implemented right now because we only have a single touch and so far I + // haven't needed it. + _state = UIGestureRecognizerStatePossible; - [_trackingTouches removeAllObjects]; } - (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer @@ -226,74 +234,72 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { } -- (void)_gesturesBegan:(NSSet *)touches withEvent:(UIEvent *)event -{ -} - -- (void)_gesturesMoved:(NSSet *)touches withEvent:(UIEvent *)event +- (void)_beginTrackingTouch:(UITouch *)touch withEvent:(UITouchEvent *)event { + if (self.enabled) { + if (!_delegateHas.shouldReceiveTouch || [_delegate gestureRecognizer:self shouldReceiveTouch:touch]) { + [touch _addGestureRecognizer:self]; + [_trackingTouches addObject:touch]; + } + } } -- (void)_gesturesEnded:(NSSet *)touches withEvent:(UIEvent *)event +- (void)_continueTrackingWithEvent:(UITouchEvent *)event { -} + NSMutableSet *began = [NSMutableSet new]; + NSMutableSet *moved = [NSMutableSet new]; + NSMutableSet *ended = [NSMutableSet new]; + NSMutableSet *cancelled = [NSMutableSet new]; + BOOL multitouchSequenceIsEnded = YES; + + for (UITouch *touch in _trackingTouches) { + if (touch.phase == UITouchPhaseBegan) { + multitouchSequenceIsEnded = NO; + [began addObject:touch]; + } else if (touch.phase == UITouchPhaseMoved) { + multitouchSequenceIsEnded = NO; + [moved addObject:touch]; + } else if (touch.phase == UITouchPhaseStationary) { + multitouchSequenceIsEnded = NO; + } else if (touch.phase == UITouchPhaseEnded) { + [ended addObject:touch]; + } else if (touch.phase == UITouchPhaseCancelled) { + [cancelled addObject:touch]; + } + } -- (void)_discreteGestures:(NSSet *)touches withEvent:(UIEvent *)event -{ -} + if (_state == UIGestureRecognizerStatePossible || _state == UIGestureRecognizerStateBegan || _state == UIGestureRecognizerStateChanged) { + if ([began count]) { + [self touchesBegan:began withEvent:event]; + } -- (BOOL)_shouldAttemptToRecognize -{ - return (self.enabled && - self.state != UIGestureRecognizerStateFailed && - self.state != UIGestureRecognizerStateCancelled && - self.state != UIGestureRecognizerStateEnded); + if ([moved count]) { + [self touchesMoved:moved withEvent:event]; + } + + if ([ended count]) { + [self touchesEnded:ended withEvent:event]; + } + + if ([cancelled count]) { + [self touchesCancelled:cancelled withEvent:event]; + } + } + + // if all the touches are ended or cancelled, then the multitouch sequence must be over - so we can reset + // our state back to normal and clear all the tracked touches, etc. to get ready for a new touch sequence + // in the future. + // this also applies to the special discrete gesture events because those events are only sent once! + if (multitouchSequenceIsEnded || event.isDiscreteGesture) { + // see note above in -setState: about the delay here! + [self performSelector:@selector(reset) withObject:nil afterDelay:0]; + } } -- (void)_recognizeTouches:(NSSet *)touches withEvent:(UIEvent *)event +- (void)_endTrackingTouch:(UITouch *)touch withEvent:(UITouchEvent *)event { - if ([self _shouldAttemptToRecognize]) { - [_trackingTouches setArray:[touches allObjects]]; - - for (UITouch *touch in _trackingTouches) { - switch (touch.phase) { - case UITouchPhaseBegan: - [self touchesBegan:touches withEvent:event]; - break; - - case UITouchPhaseMoved: - [self touchesMoved:touches withEvent:event]; - break; - - case UITouchPhaseEnded: - [self touchesEnded:touches withEvent:event]; - break; - - case UITouchPhaseCancelled: - [self touchesCancelled:touches withEvent:event]; - break; - - case _UITouchPhaseGestureBegan: - [self _gesturesBegan:touches withEvent:event]; - break; - - case _UITouchPhaseGestureChanged: - [self _gesturesMoved:touches withEvent:event]; - break; - - case _UITouchPhaseGestureEnded: - [self _gesturesEnded:touches withEvent:event]; - break; - - case _UITouchPhaseDiscreteGesture: - [self _discreteGestures:touches withEvent:event]; - break; - - default: - break; - } - } - } + [touch _removeGestureRecognizer:self]; + [_trackingTouches removeObject:touch]; } - (NSString *)description diff --git a/UIKit/Classes/UIGestureRecognizerSubclass.h b/UIKit/Classes/UIGestureRecognizerSubclass.h index 5f9987f1..78c8aeb8 100644 --- a/UIKit/Classes/UIGestureRecognizerSubclass.h +++ b/UIKit/Classes/UIGestureRecognizerSubclass.h @@ -30,11 +30,10 @@ #import "UIGestureRecognizer.h" @interface UIGestureRecognizer () +- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent*)event; // don't override @property (nonatomic,readwrite) UIGestureRecognizerState state; -- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent*)event; // don't override - // override, but be sure to call super - (void)reset; - (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer; @@ -43,5 +42,4 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; - @end diff --git a/UIKit/Classes/UIGraphics.m b/UIKit/Classes/UIGraphics.m index 7e90f9fd..97881803 100644 --- a/UIKit/Classes/UIGraphics.m +++ b/UIKit/Classes/UIGraphics.m @@ -72,7 +72,7 @@ CGFloat _UIGraphicsGetContextScaleFactor(CGContextRef ctx) void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) { if (scale == 0.f) { - scale = [UIScreen mainScreen].scale; + scale = [UIScreen mainScreen].scale ?: 1; } const size_t width = size.width * scale; diff --git a/UIKit/Classes/UIImage+UIPrivate.m b/UIKit/Classes/UIImage+UIPrivate.m index dfade4f5..efa02818 100644 --- a/UIKit/Classes/UIImage+UIPrivate.m +++ b/UIKit/Classes/UIImage+UIPrivate.m @@ -152,7 +152,6 @@ + (UIImage *)_tabBarItemImage - (id)_initWithRepresentations:(NSArray *)reps { if ([reps count] == 0) { - [self release]; self = nil; } else if ((self=[super init])) { _representations = [reps copy]; diff --git a/UIKit/Classes/UIImage.h b/UIKit/Classes/UIImage.h index 893cef15..ee810a57 100644 --- a/UIKit/Classes/UIImage.h +++ b/UIKit/Classes/UIImage.h @@ -27,9 +27,9 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import +#import "UIGeometry.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIImageOrientation) { UIImageOrientationUp, UIImageOrientationDown, // 180 deg rotation UIImageOrientationLeft, // 90 deg CCW @@ -39,7 +39,7 @@ typedef enum { UIImageOrientationDownMirrored, // horizontal flip UIImageOrientationLeftMirrored, // vertical flip UIImageOrientationRightMirrored, // vertical flip -} UIImageOrientation; +}; @interface UIImage : NSObject { @private @@ -58,6 +58,7 @@ typedef enum { - (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation; - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight; +- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets; // not correctly implemented // the draw methods will all check the scale of the current context and attempt to use the best representation it can - (void)drawAtPoint:(CGPoint)point blendMode:(CGBlendMode)blendMode alpha:(CGFloat)alpha; diff --git a/UIKit/Classes/UIImage.m b/UIKit/Classes/UIImage.m index 7948a19b..fc170979 100644 --- a/UIKit/Classes/UIImage.m +++ b/UIKit/Classes/UIImage.m @@ -73,7 +73,7 @@ - (id)initWithContentsOfFile:(NSString *)imagePath - (id)initWithData:(NSData *)data { - return [self _initWithRepresentations:[NSArray arrayWithObjects:[[[UIImageRep alloc] initWithData:data] autorelease], nil]]; + return [self _initWithRepresentations:[NSArray arrayWithObjects:[[UIImageRep alloc] initWithData:data], nil]]; } - (id)initWithCGImage:(CGImageRef)imageRef @@ -83,33 +83,28 @@ - (id)initWithCGImage:(CGImageRef)imageRef - (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation { - return [self _initWithRepresentations:[NSArray arrayWithObjects:[[[UIImageRep alloc] initWithCGImage:imageRef scale:scale] autorelease], nil]]; + return [self _initWithRepresentations:[NSArray arrayWithObjects:[[UIImageRep alloc] initWithCGImage:imageRef scale:scale], nil]]; } -- (void)dealloc -{ - [_representations release]; - [super dealloc]; -} + (UIImage *)imageWithData:(NSData *)data { - return [[[self alloc] initWithData:data] autorelease]; + return [[self alloc] initWithData:data]; } + (UIImage *)imageWithContentsOfFile:(NSString *)path { - return [[[self alloc] initWithContentsOfFile:path] autorelease]; + return [[self alloc] initWithContentsOfFile:path]; } + (UIImage *)imageWithCGImage:(CGImageRef)imageRef { - return [[[self alloc] initWithCGImage:imageRef] autorelease]; + return [[self alloc] initWithCGImage:imageRef]; } + (UIImage *)imageWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation { - return [[[self alloc] initWithCGImage:imageRef scale:scale orientation:orientation] autorelease]; + return [[self alloc] initWithCGImage:imageRef scale:scale orientation:orientation]; } - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight @@ -119,22 +114,27 @@ - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeig if ((leftCapWidth == 0 && topCapHeight == 0) || (leftCapWidth >= size.width && topCapHeight >= size.height)) { return self; } else if (leftCapWidth <= 0 || leftCapWidth >= size.width) { - return [[[UIThreePartImage alloc] initWithRepresentations:[self _representations] capSize:MIN(topCapHeight,size.height) vertical:YES] autorelease]; + return [[UIThreePartImage alloc] initWithRepresentations:[self _representations] capSize:MIN(topCapHeight,size.height) vertical:YES]; } else if (topCapHeight <= 0 || topCapHeight >= size.height) { - return [[[UIThreePartImage alloc] initWithRepresentations:[self _representations] capSize:MIN(leftCapWidth,size.width) vertical:NO] autorelease]; + return [[UIThreePartImage alloc] initWithRepresentations:[self _representations] capSize:MIN(leftCapWidth,size.width) vertical:NO]; } else { - return [[[UINinePartImage alloc] initWithRepresentations:[self _representations] leftCapWidth:leftCapWidth topCapHeight:topCapHeight] autorelease]; + return [[UINinePartImage alloc] initWithRepresentations:[self _representations] leftCapWidth:leftCapWidth topCapHeight:topCapHeight]; } } +- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets +{ + return [self stretchableImageWithLeftCapWidth:capInsets.left topCapHeight:capInsets.top]; +} + - (CGSize)size { CGSize size = CGSizeZero; UIImageRep *rep = [_representations lastObject]; const CGSize repSize = rep.imageSize; const CGFloat scale = rep.scale; - size.width = repSize.width / scale; - size.height = repSize.height / scale; + size.width = floorf(repSize.width / scale); + size.height = floorf(repSize.height / scale); return size; } @@ -212,16 +212,10 @@ BOOL UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(NSString *videoPath) { CFMutableDataRef data = CFDataCreateMutable(NULL, 0); CGImageDestinationRef dest = CGImageDestinationCreateWithData(data, kUTTypeJPEG, 1, NULL); - CFNumberRef quality = CFNumberCreate(NULL, kCFNumberCGFloatType, &compressionQuality); - CFStringRef keys[] = { kCGImageDestinationLossyCompressionQuality }; - CFTypeRef values[] = { quality }; - CFDictionaryRef properties = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, NULL, NULL); - CGImageDestinationAddImage(dest, image.CGImage, properties); - CFRelease(properties); - CFRelease(quality); + CGImageDestinationAddImage(dest, image.CGImage, (__bridge CFDictionaryRef)@{(__bridge NSString *)kCGImageDestinationLossyCompressionQuality : @(compressionQuality)}); CGImageDestinationFinalize(dest); CFRelease(dest); - return [(__bridge NSData *)data autorelease]; + return (__bridge_transfer NSMutableData *)data; } NSData *UIImagePNGRepresentation(UIImage *image) @@ -231,5 +225,5 @@ BOOL UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(NSString *videoPath) CGImageDestinationAddImage(dest, image.CGImage, NULL); CGImageDestinationFinalize(dest); CFRelease(dest); - return [(__bridge NSData *)data autorelease]; + return (__bridge_transfer NSMutableData *)data; } diff --git a/UIKit/Classes/UIImageAppKitIntegration.h b/UIKit/Classes/UIImageAppKitIntegration.h index 15c2b175..745a4713 100644 --- a/UIKit/Classes/UIImageAppKitIntegration.h +++ b/UIKit/Classes/UIImageAppKitIntegration.h @@ -35,4 +35,46 @@ + (id)imageWithNSImage:(NSImage *)theImage; - (id)initWithNSImage:(NSImage *)theImage; - (NSImage *)NSImage; + +/* + this is a hack to support screen scale factor changes (retina) which iOS doesn't + have a decent way to support as far as I can tell. + + these will build a UIImage object from multiple source UIImages that are already + at different scales and when the resulting UIImage is drawn, it should choose the + correct one based on the scale of the underlying context at the time it is drawn. + + pass an array of UIImage objects at different scales that represent the same image. + + each image must have a different .scale property value, no duplicates allowed! + + each image must be the same size as compared to the others: + - eg: and + + NOTE: internally, UIImage already loads both @1x and @2x versions of image files if + they are present (-initWithNSImage: does something similar), so for the most part you + probably don't need this. the primary purpose of this is if you are custom drawing + something using something like UIGraphicsBeginImageContext() and don't know what the + scale factor of the window might currently be now or in the future. + + EXAMPLE: + + // render @1x + UIGraphicsBeginImageContextWithOptions(size, NO, 1); + .. draw stuff .. + UIImage *image1x = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + // render @2x + UIGraphicsBeginImageContextWithOptions(size, NO, 2); + .. draw stuff .. + UIImage *image2x = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + // put them together + UIImage *finalImage = [UIImage imageWithScaledImages:@[image1, image2]]; + */ ++ (id)imageWithScaledImages:(NSArray *)images; +- (id)initWithScaledImages:(NSArray *)images; + @end diff --git a/UIKit/Classes/UIImageAppKitIntegration.m b/UIKit/Classes/UIImageAppKitIntegration.m index 01b7a13a..c3804c2e 100644 --- a/UIKit/Classes/UIImageAppKitIntegration.m +++ b/UIKit/Classes/UIImageAppKitIntegration.m @@ -37,14 +37,14 @@ static UIImageRep *UIImageRepFromNSImageRep(NSImageRep *rep, NSRect rect, CGFloat scale) { - return [[[UIImageRep alloc] initWithCGImage:[rep CGImageForProposedRect:&rect context:nil hints:nil] scale:scale] autorelease]; + return [[UIImageRep alloc] initWithCGImage:[rep CGImageForProposedRect:&rect context:nil hints:nil] scale:scale]; } @implementation UIImage (AppKitIntegration) + (id)imageWithNSImage:(NSImage *)theImage { - return [[[self alloc] initWithNSImage:theImage] autorelease]; + return [[self alloc] initWithNSImage:theImage]; } - (id)initWithNSImage:(NSImage *)theImage @@ -75,9 +75,9 @@ - (NSImage *)NSImage NSImage *cached = objc_getAssociatedObject(self, UIImageAssociatedNSImageKey); if (!cached) { - cached = [[[NSImage alloc] initWithSize:NSSizeFromCGSize(self.size)] autorelease]; + cached = [[NSImage alloc] initWithSize:NSSizeFromCGSize(self.size)]; for (UIImageRep *rep in [self _representations]) { - [cached addRepresentation:[[[NSBitmapImageRep alloc] initWithCGImage:rep.CGImage] autorelease]]; + [cached addRepresentation:[[NSBitmapImageRep alloc] initWithCGImage:rep.CGImage]]; } objc_setAssociatedObject(self, UIImageAssociatedNSImageKey, cached, OBJC_ASSOCIATION_RETAIN); } @@ -85,4 +85,26 @@ - (NSImage *)NSImage return cached; } ++ (id)imageWithScaledImages:(NSArray *)images +{ + return [[self alloc] initWithScaledImages:images]; +} + +- (id)initWithScaledImages:(NSArray *)images +{ + NSMutableArray *reps = [NSMutableArray arrayWithCapacity:[images count]]; + NSMutableSet *scaleFactors = [NSMutableSet setWithCapacity:[images count]]; + + for (UIImage *img in images) { + NSNumber *scale = [NSNumber numberWithFloat:img.scale]; + assert(CGSizeEqualToSize(img.size, [[images lastObject] size])); + assert(![scaleFactors containsObject:scale]); + + [scaleFactors addObject:scale]; + [reps addObject:[[UIImageRep alloc] initWithCGImage:img.CGImage scale:img.scale]]; + } + + return [self _initWithRepresentations:reps]; +} + @end diff --git a/UIKit/Classes/UIImagePickerController.h b/UIKit/Classes/UIImagePickerController.h index 1f3e042f..43de2487 100644 --- a/UIKit/Classes/UIImagePickerController.h +++ b/UIKit/Classes/UIImagePickerController.h @@ -29,12 +29,11 @@ #import "UINavigationController.h" -enum { +typedef NS_ENUM(NSInteger, UIImagePickerControllerSourceType) { UIImagePickerControllerSourceTypePhotoLibrary, UIImagePickerControllerSourceTypeCamera, UIImagePickerControllerSourceTypeSavedPhotosAlbum }; -typedef NSUInteger UIImagePickerControllerSourceType; extern NSString *const UIImagePickerControllerMediaType; extern NSString *const UIImagePickerControllerOriginalImage; @@ -45,17 +44,12 @@ extern NSString *const UIImagePickerControllerMediaURL; @protocol UIImagePickerControllerDelegate @end -@interface UIImagePickerController : UINavigationController { -@private - UIImagePickerControllerSourceType _sourceType; - NSArray *_mediaTypes; -} - +@interface UIImagePickerController : UINavigationController + (NSArray *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType; + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType; @property (nonatomic) UIImagePickerControllerSourceType sourceType; -@property (nonatomic,assign) id delegate; -@property (nonatomic,copy) NSArray *mediaTypes; - +@property (nonatomic, assign) id delegate; +@property (nonatomic, copy) NSArray *mediaTypes; +@property (nonatomic) BOOL allowsEditing; @end diff --git a/UIKit/Classes/UIImagePickerController.m b/UIKit/Classes/UIImagePickerController.m index f4fb4a2f..11dcc4ec 100644 --- a/UIKit/Classes/UIImagePickerController.m +++ b/UIKit/Classes/UIImagePickerController.m @@ -36,8 +36,6 @@ NSString *const UIImagePickerControllerMediaURL = @"UIImagePickerControllerMediaURL"; @implementation UIImagePickerController -@synthesize sourceType=_sourceType, mediaTypes=_mediaTypes; -@dynamic delegate; + (NSArray *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType { @@ -49,10 +47,4 @@ + (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType return NO; } -- (void)dealloc -{ - [_mediaTypes release]; - [super dealloc]; -} - @end diff --git a/UIKit/Classes/UIImageRep.h b/UIKit/Classes/UIImageRep.h index 423700c0..c62b68ae 100644 --- a/UIKit/Classes/UIImageRep.h +++ b/UIKit/Classes/UIImageRep.h @@ -29,12 +29,7 @@ #import -@interface UIImageRep : NSObject { - CGFloat _scale; - CGImageSourceRef _imageSource; - NSInteger _imageSourceIndex; - CGImageRef _image; -} +@interface UIImageRep : NSObject + (NSArray *)imageRepsWithContentsOfFile:(NSString *)file; diff --git a/UIKit/Classes/UIImageRep.m b/UIKit/Classes/UIImageRep.m index 2d8f1fa2..fe8ea0d5 100644 --- a/UIKit/Classes/UIImageRep.m +++ b/UIKit/Classes/UIImageRep.m @@ -33,11 +33,14 @@ static CGImageSourceRef CreateCGImageSourceWithFile(NSString *imagePath) { NSString *macPath = [[[imagePath stringByDeletingPathExtension] stringByAppendingString:@"~mac"] stringByAppendingPathExtension:[imagePath pathExtension]]; - return CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:macPath], NULL) ?: CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:imagePath], NULL); + return CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:macPath], NULL) ?: CGImageSourceCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:imagePath], NULL); } -@implementation UIImageRep -@synthesize scale=_scale; +@implementation UIImageRep { + CGImageSourceRef _imageSource; + NSInteger _imageSourceIndex; + CGImageRef _CGImage; +} + (NSArray *)_imageRepsWithContentsOfMultiResolutionFile:(NSString *)imagePath { @@ -57,13 +60,11 @@ + (NSArray *)_imageRepsWithContentsOfFiles:(NSString *)imagePath if (src1X) { UIImageRep *rep = [[UIImageRep alloc] initWithCGImageSource:src1X imageIndex:0 scale:1]; if (rep) [reps addObject:rep]; - [rep release]; CFRelease(src1X); } if (src2X) { UIImageRep *rep = [[UIImageRep alloc] initWithCGImageSource:src2X imageIndex:0 scale:2]; if (rep) [reps addObject:rep]; - [rep release]; CFRelease(src2X); } @@ -78,7 +79,6 @@ + (NSArray *)imageRepsWithContentsOfFile:(NSString *)imagePath - (id)initWithCGImageSource:(CGImageSourceRef)source imageIndex:(NSUInteger)index scale:(CGFloat)scale { if (!source || CGImageSourceGetCount(source) <= index) { - [self release]; self = nil; } else if ((self=[super init])) { CFRetain(source); @@ -92,23 +92,21 @@ - (id)initWithCGImageSource:(CGImageSourceRef)source imageIndex:(NSUInteger)inde - (id)initWithCGImage:(CGImageRef)image scale:(CGFloat)scale { if (!image) { - [self release]; self = nil; } else if ((self=[super init])) { _scale = scale; - _image = CGImageRetain(image); + _CGImage = CGImageRetain(image); } return self; } - (id)initWithData:(NSData *)data { - CGImageSourceRef src = data? CGImageSourceCreateWithData((CFDataRef)data, NULL) : NULL; + CGImageSourceRef src = data? CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL) : NULL; if (src) { self = [self initWithCGImageSource:src imageIndex:0 scale:1]; CFRelease(src); } else { - [self release]; self = nil; } @@ -117,22 +115,21 @@ - (id)initWithData:(NSData *)data - (void)dealloc { - if (_image) CGImageRelease(_image); + if (_CGImage) CGImageRelease(_CGImage); if (_imageSource) CFRelease(_imageSource); - [super dealloc]; } - (BOOL)isLoaded { - return (_image != NULL); + return (_CGImage != NULL); } - (BOOL)isOpaque { BOOL opaque = NO; - if (_image) { - CGImageAlphaInfo info = CGImageGetAlphaInfo(_image); + if (_CGImage) { + CGImageAlphaInfo info = CGImageGetAlphaInfo(_CGImage); opaque = (info == kCGImageAlphaNone) || (info == kCGImageAlphaNoneSkipLast) || (info == kCGImageAlphaNoneSkipFirst); } else if (_imageSource) { CFDictionaryRef info = CGImageSourceCopyPropertiesAtIndex(_imageSource, _imageSourceIndex, NULL); @@ -147,9 +144,9 @@ - (CGSize)imageSize { CGSize size = CGSizeZero; - if (_image) { - size.width = CGImageGetWidth(_image); - size.height = CGImageGetHeight(_image); + if (_CGImage) { + size.width = CGImageGetWidth(_CGImage); + size.height = CGImageGetHeight(_CGImage); } else if (_imageSource) { CFDictionaryRef info = CGImageSourceCopyPropertiesAtIndex(_imageSource, _imageSourceIndex, NULL); CFNumberRef width = CFDictionaryGetValue(info, kCGImagePropertyPixelWidth); @@ -167,13 +164,13 @@ - (CGSize)imageSize - (CGImageRef)CGImage { // lazy load if we only have an image source - if (!_image && _imageSource) { - _image = CGImageSourceCreateImageAtIndex(_imageSource, _imageSourceIndex, NULL); + if (!_CGImage && _imageSource) { + _CGImage = CGImageSourceCreateImageAtIndex(_imageSource, _imageSourceIndex, NULL); CFRelease(_imageSource); _imageSource = NULL; } - return _image; + return _CGImage; } - (void)drawInRect:(CGRect)rect fromRect:(CGRect)fromRect diff --git a/UIKit/Classes/UIImageView+UIPrivate.h b/UIKit/Classes/UIImageView+UIPrivate.h index 3798374b..5f3476d0 100644 --- a/UIKit/Classes/UIImageView+UIPrivate.h +++ b/UIKit/Classes/UIImageView+UIPrivate.h @@ -29,12 +29,12 @@ #import "UIImageView.h" -enum { +typedef NS_ENUM(NSInteger, _UIImageViewDrawMode) { _UIImageViewDrawModeNormal, _UIImageViewDrawModeHighlighted, _UIImageViewDrawModeDisabled, }; @interface UIImageView (UIPrivate) -- (void)_setDrawMode:(NSInteger)drawMode; +- (void)_setDrawMode:(_UIImageViewDrawMode)drawMode; @end diff --git a/UIKit/Classes/UIImageView.h b/UIKit/Classes/UIImageView.h index 2645d1dc..7b0aaef8 100644 --- a/UIKit/Classes/UIImageView.h +++ b/UIKit/Classes/UIImageView.h @@ -31,30 +31,18 @@ @class UIImage, CAKeyframeAnimation; -@interface UIImageView : UIView { -@private - UIImage *_image; - NSArray *_animationImages; - NSArray *_highlightedAnimationImages; - NSTimeInterval _animationDuration; - NSInteger _animationRepeatCount; - UIImage *_highlightedImage; - BOOL _highlighted; - NSInteger _drawMode; -} - +@interface UIImageView : UIView - (id)initWithImage:(UIImage *)theImage; - (void)startAnimating; - (void)stopAnimating; - (BOOL)isAnimating; -@property (nonatomic, retain) UIImage *highlightedImage; +@property (nonatomic, strong) UIImage *highlightedImage; @property (nonatomic, getter=isHighlighted) BOOL highlighted; -@property (nonatomic, retain) UIImage *image; +@property (nonatomic, strong) UIImage *image; @property (nonatomic, copy) NSArray *animationImages; @property (nonatomic, copy) NSArray *highlightedAnimationImages; @property (nonatomic) NSTimeInterval animationDuration; @property (nonatomic) NSInteger animationRepeatCount; - @end diff --git a/UIKit/Classes/UIImageView.m b/UIKit/Classes/UIImageView.m index 81d5cca2..50a4fafa 100644 --- a/UIKit/Classes/UIImageView.m +++ b/UIKit/Classes/UIImageView.m @@ -47,9 +47,9 @@ return CGImages; } -@implementation UIImageView -@synthesize image=_image, animationImages=_animationImages, animationDuration=_animationDuration, highlightedImage=_highlightedImage, highlighted=_highlighted; -@synthesize animationRepeatCount=_animationRepeatCount, highlightedAnimationImages=_highlightedAnimationImages; +@implementation UIImageView { + _UIImageViewDrawMode _drawMode; +} + (BOOL)_instanceImplementsDrawRect { @@ -81,14 +81,6 @@ - (id)initWithImage:(UIImage *)theImage return self; } -- (void)dealloc -{ - [_animationImages release]; - [_image release]; - [_highlightedImage release]; - [_highlightedAnimationImages release]; - [super dealloc]; -} - (CGSize)sizeThatFits:(CGSize)size { @@ -110,8 +102,7 @@ - (void)setHighlighted:(BOOL)h - (void)setImage:(UIImage *)newImage { if (_image != newImage) { - [_image release]; - _image = [newImage retain]; + _image = newImage; if (!_highlighted || !_highlightedImage) { [self setNeedsDisplay]; } @@ -121,8 +112,7 @@ - (void)setImage:(UIImage *)newImage - (void)setHighlightedImage:(UIImage *)newImage { if (_highlightedImage != newImage) { - [_highlightedImage release]; - _highlightedImage = [newImage retain]; + _highlightedImage = newImage; if (_highlighted) { [self setNeedsDisplay]; } @@ -134,7 +124,7 @@ - (BOOL)_hasResizableImage return (_image.topCapHeight > 0 || _image.leftCapWidth > 0); } -- (void)_setDrawMode:(NSInteger)drawMode +- (void)_setDrawMode:(_UIImageViewDrawMode)drawMode { if (drawMode != _drawMode) { _drawMode = drawMode; diff --git a/UIKit/Classes/UIInputController.h b/UIKit/Classes/UIInputController.h index b7e2bcb3..c606d055 100644 --- a/UIKit/Classes/UIInputController.h +++ b/UIKit/Classes/UIInputController.h @@ -27,22 +27,20 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import +#import "UIResponder.h" +#import "UITextInput.h" @class UIView, UIWindow; -@interface UIInputController : NSObject { - UIWindow *_inputWindow; - UIView *_inputAccessoryView; - UIView *_inputView; -} +@interface UIInputController : NSObject + (UIInputController *)sharedInputController; - (void)setInputVisible:(BOOL)visible animated:(BOOL)animated; -@property (nonatomic, retain) UIView *inputAccessoryView; -@property (nonatomic, retain) UIView *inputView; +@property (nonatomic, strong) UIView *inputAccessoryView; +@property (nonatomic, strong) UIView *inputView; +@property (nonatomic, weak) UIResponder *keyInputResponder; @property (nonatomic, assign) BOOL inputVisible; diff --git a/UIKit/Classes/UIInputController.m b/UIKit/Classes/UIInputController.m index 984eef43..f18ecc7a 100644 --- a/UIKit/Classes/UIInputController.m +++ b/UIKit/Classes/UIInputController.m @@ -47,8 +47,9 @@ } -@implementation UIInputController -@synthesize inputAccessoryView=_inputAccessoryView, inputView=_inputView; +@implementation UIInputController { + UIWindow *_inputWindow; +} + (UIInputController *)sharedInputController { @@ -77,17 +78,12 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_inputWindow release]; - [_inputAccessoryView release]; - [_inputView release]; - [super dealloc]; } // finds the first real UIView that the current key window's first responder "belongs" to so we know where to display the input window - (UIView *)_referenceView { - UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; - UIResponder *firstResponder = [keyWindow _firstResponder]; + UIResponder *firstResponder = self.keyInputResponder; if (firstResponder) { UIResponder *currentResponder = firstResponder; @@ -143,11 +139,13 @@ - (void)_repositionInputWindow - (void)_viewChangedNotification:(NSNotification *)note { - UIView *view = [note object]; - UIView *referenceView = [self _referenceView]; + if (self.inputVisible) { + UIView *view = [note object]; + UIView *referenceView = [self _referenceView]; - if (self.inputVisible && (view == referenceView || [ContainerForView(referenceView) isDescendantOfView:view])) { - [self _repositionInputWindow]; + if (view == referenceView || [ContainerForView(referenceView) isDescendantOfView:view]) { + [self _repositionInputWindow]; + } } } @@ -191,9 +189,8 @@ - (void)setInputAccessoryView:(UIView *)view { if (view != _inputAccessoryView) { [_inputAccessoryView removeFromSuperview]; - [_inputAccessoryView release]; - _inputAccessoryView = [view retain]; + _inputAccessoryView = view; [_inputWindow addSubview:_inputAccessoryView]; } } @@ -202,9 +199,8 @@ - (void)setInputView:(UIView *)view { if (view != _inputView) { [_inputView removeFromSuperview]; - [_inputView release]; - _inputView = [view retain]; + _inputView = view; [_inputWindow addSubview:_inputView]; } } diff --git a/UIKit/Classes/UIInterface.h b/UIKit/Classes/UIInterface.h index acc01943..a8b7d38f 100644 --- a/UIKit/Classes/UIInterface.h +++ b/UIKit/Classes/UIInterface.h @@ -31,13 +31,17 @@ #import "UIFont.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIBarStyle) { UIBarStyleDefault = 0, UIBarStyleBlack = 1, UIBarStyleBlackOpaque = 1, // Deprecated UIBarStyleBlackTranslucent = 2 // Deprecated -} UIBarStyle; +}; +typedef NS_ENUM(NSInteger, UIBarMetrics) { + UIBarMetricsDefault, + UIBarMetricsLandscapePhone, +}; @interface UIColor (UIColorSystemColors) + (UIColor *)groupTableViewBackgroundColor; diff --git a/UIKit/Classes/UIKey.h b/UIKit/Classes/UIKey.h index 019c75e1..871eb032 100644 --- a/UIKit/Classes/UIKey.h +++ b/UIKit/Classes/UIKey.h @@ -29,11 +29,13 @@ #import +@class NSEvent; + // NOTE: This does not come from Apple's UIKit and only exist to solve some current problems. // I have no idea what Apple will do with keyboard handling. If they ever expose that stuff publically, // then all of this should change to reflect the official API. -typedef enum { +typedef NS_ENUM(NSInteger, UIKeyType) { UIKeyTypeCharacter, // the catch-all/default... I wouldn't depend much on this at this point UIKeyTypeUpArrow, UIKeyTypeDownArrow, @@ -47,16 +49,11 @@ typedef enum { UIKeyTypeEnd, UIKeyTypePageUp, UIKeyTypePageDown, -} UIKeyType; + UIKeyTypeEscape, +}; -@interface UIKey : NSObject { -@private - unsigned short _keyCode; - NSString *_characters; - NSString *_charactersWithModifiers; - NSUInteger _modifierFlags; - BOOL _repeat; -} +@interface UIKey : NSObject +- (id)initWithNSEvent:(NSEvent *)event; @property (nonatomic, readonly) UIKeyType type; @property (nonatomic, readonly) unsigned short keyCode; @@ -68,5 +65,5 @@ typedef enum { @property (nonatomic, readonly, getter=isControlKeyPressed) BOOL controlKeyPressed; @property (nonatomic, readonly, getter=isOptionKeyPressed) BOOL optionKeyPressed; @property (nonatomic, readonly, getter=isCommandKeyPressed) BOOL commandKeyPressed; - +@property (nonatomic, readonly) SEL action; // an action associated with the key press, or null @end diff --git a/UIKit/Classes/UIKey.m b/UIKit/Classes/UIKey.m index 7dbed326..a5782e7b 100644 --- a/UIKit/Classes/UIKey.m +++ b/UIKit/Classes/UIKey.m @@ -27,11 +27,12 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIKey+UIPrivate.h" +#import "UIKey.h" #import -@implementation UIKey -@synthesize keyCode=_keyCode, characters=_characters, charactersWithModifiers=_charactersWithModifiers, repeat=_repeat; +@implementation UIKey { + NSUInteger _modifierFlags; +} - (id)initWithNSEvent:(NSEvent *)event { @@ -45,15 +46,13 @@ - (id)initWithNSEvent:(NSEvent *)event return self; } -- (void)dealloc -{ - [_characters release]; - [_charactersWithModifiers release]; - [super dealloc]; -} - (UIKeyType)type { + if (_keyCode == 53) { + return UIKeyTypeEscape; + } + if ([_characters length] > 0) { switch ([_characters characterAtIndex:0]) { case NSUpArrowFunctionKey: return UIKeyTypeUpArrow; @@ -99,4 +98,17 @@ - (BOOL)isCommandKeyPressed return (_modifierFlags & NSCommandKeyMask) == NSCommandKeyMask; } +- (SEL)action +{ + if (self.type == UIKeyTypeEnter || (self.type == UIKeyTypeReturn && self.commandKeyPressed)) { + return @selector(commitOperation:); + } + + if (self.type == UIKeyTypeEscape || (self.commandKeyPressed && [self.characters isEqual:@"."])) { + return @selector(cancelOperation:); + } + + return NULL; +} + @end diff --git a/UIKit/Classes/UIKit.h b/UIKit/Classes/UIKit.h index 24ab4f36..6f64d7ee 100644 --- a/UIKit/Classes/UIKit.h +++ b/UIKit/Classes/UIKit.h @@ -108,13 +108,17 @@ #import "UISwipeGestureRecognizer.h" #import "UIDatePicker.h" #import "UIAppearance.h" +#import "UITextInput.h" // non-standard imports -#import "UIKey.h" #import "UIScrollWheelGestureRecognizer.h" -// only add if core data is included on 10.6 -#import "NSFetchedResultsController.h" +// osx imports +#import +#import +#import +#import +#import // SystemConfiguration-Helper #define kSCNetworkReachabilityFlagsIsWWAN kSCNetworkReachabilityFlagsConnectionOnDemand diff --git a/UIKit/Classes/UIKitView.h b/UIKit/Classes/UIKitView.h index acd75515..7db3c32d 100644 --- a/UIKit/Classes/UIKitView.h +++ b/UIKit/Classes/UIKitView.h @@ -29,22 +29,14 @@ #import #import "UIApplicationDelegate.h" +#import "UIScreen.h" +#import "UIWindow.h" -@class UIScreen, UIWindow; +@interface UIKitView : NSView -@interface UIKitView : NSView { - UIScreen *_screen; - UIWindow *_mainWindow; - NSTrackingArea *_trackingArea; -} - -// if UIApplication's keyWindow is on the screen represented by this UIKitView, this will send -canPerformAction:withSender: to the keyWindow's -// current first responder with the given action and sender and return the result. if the keyWindow is not on this screen, it always returns NO. -- (BOOL)firstResponderCanPerformAction:(SEL)action withSender:(id)sender; - -// if UIApplication's keyWindow is on the screen represented by this UIKitView, this will send the action down the responder chain starting with -// the keyWindow's first responder. if the keyWindow is not on this screen, nothing happens. -- (void)sendActionToFirstResponder:(SEL)action from:(id)sender; +// returns the UIView (or nil) that successfully responds to a -hitTest:withEvent: at the given point. +// the point is specified in this view's coordinate system (unlike NSView's hitTest method). +- (UIView *)hitTestUIView:(NSPoint)point; // this is an optional method // it will set the sharedApplication's delegate to appDelegate. if delay is >0, it will then look in the app bundle for @@ -55,12 +47,15 @@ // ** IMPORTANT: appDelegate is *not* retained! ** - (void)launchApplicationWithDelegate:(id)appDelegate afterDelay:(NSTimeInterval)delay; +// these are sort of hacks used internally. I don't know if there's much need for them from the outside, really. +- (void)cancelTouchesInView:(UIView *)view; +- (void)sendStationaryTouches; + // this is an optional property to make it quick and easy to get a window to start adding views to. // created on-demand to be the size of the UIScreen.bounds, flexible width/height, and calls makeKeyAndVisible when it is first created -@property (nonatomic, retain, readonly) UIWindow *UIWindow; +@property (nonatomic, strong, readonly) UIWindow *UIWindow; // a UIKitView owns a single UIScreen. when the UIKitView is part of an NSWindow hierarchy, the UIScreen appears as a connected screen in // [UIScreen screens], etc. -@property (nonatomic, retain, readonly) UIScreen *UIScreen; - +@property (nonatomic, strong, readonly) UIScreen *UIScreen; @end diff --git a/UIKit/Classes/UIKitView.m b/UIKit/Classes/UIKitView.m index 9e3f1b61..471cd4d7 100644 --- a/UIKit/Classes/UIKitView.m +++ b/UIKit/Classes/UIKitView.m @@ -28,61 +28,85 @@ */ #import "UIKitView.h" -#import "UIApplication+UIPrivate.h" +#import "UIApplication.h" #import "UIScreen+UIPrivate.h" +#import "UIScreenAppKitIntegration.h" #import "UIWindow+UIPrivate.h" #import "UIImage.h" #import "UIImageView.h" #import "UIColor.h" +#import "UITouchEvent.h" +#import "UITouch+UIPrivate.h" +#import "UIKey.h" +#import "UINSResponderShim.h" +#import "UIViewControllerAppKitIntegration.h" -@implementation UIKitView -@synthesize UIScreen=_screen; +/* + An older design of Chameleon had the singlular multi-touch event living in UIApplication because that made sense at the time. + However it was needlessly awkward to send events from here to the UIApplication and then have to decode them all again, etc. + It seemingly gained nothing. Also, while I don't know how UIKit would handle this situation, I'm not sure it makes sense to + have a single multitouch sequence span multiple screens anyway. There are some cases where that might kinda make sense, but + I'm having some doubts that this is how iOS would be setup anyway. (It's hard to really know without some deep digging since + I don't know if iOS even supports touch events on any screen other than the main one anyway, but it doesn't matter right now.) + + The benefit of having it here is that this is right where the touches happen. There's no ambiguity about exactly which + screen/NSView the event occured on, and there's no need to pass that info around deep into other parts of the code, either. + It can be dealt with here and now and life can go on and things don't have to get weirdly complicated deep down the rabbit + hole. In theory. + */ -- (void)setScreenLayer -{ - [self setWantsLayer:YES]; +@interface UIKitView () +@end - CALayer *screenLayer = [_screen _layer]; - CALayer *myLayer = [self layer]; - - [myLayer addSublayer:screenLayer]; - screenLayer.frame = myLayer.bounds; - screenLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; - myLayer.geometryFlipped = YES; +@implementation UIKitView { + UITouchEvent *_touchEvent; + UITouch *_mouseMoveTouch; + UIWindow *_UIWindow; + NSTrackingArea *_trackingArea; + UINSResponderShim *_responderShim; } - (id)initWithFrame:(NSRect)frame { if ((self = [super initWithFrame:frame])) { - _screen = [[UIScreen alloc] init]; - [self setScreenLayer]; + _mouseMoveTouch = [[UITouch alloc] init]; + _UIScreen = [[UIScreen alloc] init]; + _responderShim = [[UINSResponderShim alloc] init]; + + _responderShim.delegate = self; + + [self configureScreenLayer]; } return self; } -- (void)dealloc +- (void)awakeFromNib { - [_screen release]; - [_mainWindow release]; - [_trackingArea release]; - [super dealloc]; + [self configureScreenLayer]; } -- (void)awakeFromNib +- (void)configureScreenLayer { - [self setScreenLayer]; + [self setWantsLayer:YES]; + + CALayer *screenLayer = [_UIScreen _layer]; + CALayer *myLayer = [self layer]; + + [myLayer addSublayer:screenLayer]; + screenLayer.frame = myLayer.bounds; + screenLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; } - (UIWindow *)UIWindow { - if (!_mainWindow) { - _mainWindow = [(UIWindow *)[UIWindow alloc] initWithFrame:_screen.bounds]; - _mainWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _mainWindow.screen = _screen; - [_mainWindow makeKeyAndVisible]; + if (!_UIWindow) { + _UIWindow = [[UIWindow alloc] initWithFrame:_UIScreen.bounds]; + _UIWindow.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _UIWindow.screen = _UIScreen; + [_UIWindow makeKeyAndVisible]; } - return _mainWindow; + return _UIWindow; } - (BOOL)isFlipped @@ -90,9 +114,38 @@ - (BOOL)isFlipped return YES; } +- (BOOL)acceptsFirstResponder +{ + // we want to accept, but we have to make sure one of our NSView children isn't already the first responder + // because we don't want to let the mouse just steal that away here. If a pure-UIKit object gets clicked on + // and decides to become first responder, it'll take it itself and things should sort itself out from there + // (so stuff like a selected NSTextView would be resigned in the process of the new object becoming first + // responder so we don't have to let AppKit handle it here in that case and returning NO should be okay + // because by the time this is called again, the native AppKit control has already been told to resign) + + // the reason we can't just blindly accept first responder is that there are special situations like the + // inputAccessoryViews which live inside our UIKitView and are implemented as UIKit code, but are often + // used while the user has a native NSTextView as the first responder because they are typing in it. If + // we didn't do this checking here, the click outside of the NSTextView would register as a click on this + // UIKitView, and if we just returned YES here, AppKit would happily resign first responder from the text + // view and set it for this UIKitView which causes the inputAccessoryView to disappear! + + NSResponder *responder = [(NSWindow *)[self window] firstResponder]; + + while (responder) { + if (responder == self) { + return NO; + } else { + responder = [responder nextResponder]; + } + } + + return YES; +} + - (void)updateUIKitView { - [_screen _setUIKitView:(self.superview && self.window)? self : nil]; + [_UIScreen _setUIKitView:(self.superview && self.window)? self : nil]; } - (void)viewDidMoveToSuperview @@ -107,108 +160,155 @@ - (void)viewDidMoveToWindow [self updateUIKitView]; } -- (BOOL)acceptsFirstResponder +- (void)updateTrackingAreas { - // only accept first responder status if something else within our view isn't already the first responder - // and if our screen has something that can become first responder - // I have no idea if this is sane behavior or not. There's an issue with things like inputAccesoryViews - // because the NSTextView might be the real first responder (from AppKit's point of view) and any click - // outside of it could change the first responder status. This means that clicks on the inputAccessoryView - // could "steal" first responder away from the NSTextView if this always returns YES, but on the other - // hand we shouldn't always return NO here because pure-UIKit objects could be first responder, too, and - // in theory they'd expect to get keyboard events or something like that. So....... yeah.. I dunno. + [super updateTrackingAreas]; + [self removeTrackingArea:_trackingArea]; + _trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingCursorUpdate|NSTrackingMouseMoved|NSTrackingInVisibleRect|NSTrackingActiveInKeyWindow|NSTrackingMouseEnteredAndExited owner:self userInfo:nil]; + [self addTrackingArea:_trackingArea]; +} - NSResponder *responder = [(NSWindow *)[self window] firstResponder]; - BOOL accept = !responder || ([[UIApplication sharedApplication] _firstResponderForScreen:_screen] != nil); +- (UIView *)hitTestUIView:(NSPoint)point +{ + NSMutableArray *sortedWindows = [_UIScreen.windows mutableCopy]; + [sortedWindows sortUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"windowLevel" ascending:NO]]]; - // if we might want to accept, lets make sure that one of our children isn't already the first responder - // because we don't want to let the mouse just steal that away here. If a pure-UIKit object gets clicked on and - // decides to become first responder, it'll take it itself and things should sort itself out from there - // (so stuff like a selected NSTextView would be resigned in the process of the new object becoming first - // responder so we don't have to let AppKit handle it in that case and returning NO here should be okay) - if (accept) { - while (responder) { - if (responder == self) { - return NO; - } else { - responder = [responder nextResponder]; - } - } + for (UIWindow *window in sortedWindows) { + const CGPoint windowPoint = [window convertPoint:point fromWindow:nil]; + UIView *hitView = [window hitTest:windowPoint withEvent:nil]; + if (hitView) return hitView; + } + + return nil; +} + +- (void)launchApplicationWithDefaultWindow:(UIWindow *)defaultWindow +{ + UIApplication *app = [UIApplication sharedApplication]; + id appDelegate = app.delegate; + + if ([appDelegate respondsToSelector:@selector(application:didFinishLaunchingWithOptions:)]) { + [appDelegate application:app didFinishLaunchingWithOptions:nil]; + } else if ([appDelegate respondsToSelector:@selector(applicationDidFinishLaunching:)]) { + [appDelegate applicationDidFinishLaunching:app]; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidFinishLaunchingNotification object:app]; + + if ([appDelegate respondsToSelector:@selector(applicationDidBecomeActive:)]) { + [appDelegate applicationDidBecomeActive:app]; } - return accept; + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidBecomeActiveNotification object:app]; + + defaultWindow.hidden = YES; } -- (BOOL)firstResponderCanPerformAction:(SEL)action withSender:(id)sender +- (void)launchApplicationWithDelegate:(id)appDelegate afterDelay:(NSTimeInterval)delay { - return [[UIApplication sharedApplication] _firstResponderCanPerformAction:action withSender:sender fromScreen:_screen]; + [[UIApplication sharedApplication] setDelegate:appDelegate]; + + if (delay) { + UIImage *defaultImage = [UIImage imageNamed:@"Default-Landscape.png"]; + UIImageView *defaultImageView = [[UIImageView alloc] initWithImage:defaultImage]; + defaultImageView.contentMode = UIViewContentModeCenter; + + UIWindow *defaultWindow = [(UIWindow *)[UIWindow alloc] initWithFrame:_UIScreen.bounds]; + defaultWindow.userInteractionEnabled = NO; + defaultWindow.screen = _UIScreen; + defaultWindow.backgroundColor = [UIColor blackColor]; // dunno.. + defaultWindow.opaque = YES; + [defaultWindow addSubview:defaultImageView]; + [defaultWindow makeKeyAndVisible]; + [self performSelector:@selector(launchApplicationWithDefaultWindow:) withObject:defaultWindow afterDelay:delay]; + } else { + [self launchApplicationWithDefaultWindow:nil]; + } } -- (void)sendActionToFirstResponder:(SEL)action from:(id)sender +#pragma mark responder chain muckery + +- (void)setNextResponder:(NSResponder *)aResponder { - [[UIApplication sharedApplication] _sendActionToFirstResponder:action withSender:sender fromScreen:_screen]; + [super setNextResponder:_responderShim]; + [_responderShim setNextResponder:aResponder]; } -- (BOOL)respondsToSelector:(SEL)cmd +- (UIResponder *)responderForResponderShim:(UINSResponderShim *)shim { - if (cmd == @selector(copy:) || - cmd == @selector(cut:) || - cmd == @selector(delete:) || - cmd == @selector(paste:) || - cmd == @selector(select:) || - cmd == @selector(selectAll:) || - cmd == @selector(commit:) || - cmd == @selector(cancel:)) { - return [self firstResponderCanPerformAction:cmd withSender:nil]; - } else if (cmd == @selector(cancelOperation:)) { - return [self firstResponderCanPerformAction:@selector(cancel:) withSender:nil]; - } else { - return [super respondsToSelector:cmd]; + UIWindow *keyWindow = _UIScreen.keyWindow; + UIResponder *responder = [keyWindow _firstResponder]; + + if (!responder) { + UIViewController *controller = keyWindow.rootViewController; + + while (controller) { + // for the sake of completeness, we check the controller's presentedViewController first, because such things are + // supposed to kind of supercede the view controller itself - however we don't currently support them so it just + // returns nil all the time anyway, but what the heck, eh? + if (controller.presentedViewController) { + controller = controller.presentedViewController; + } else { + UIViewController *childController = [controller defaultResponderChildViewController]; + + if (childController) { + controller = childController; + } else { + break; + } + } + } + + responder = [controller defaultResponder]; } + + return responder; } -- (void)copy:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } -- (void)cut:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } -- (void)delete:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } -- (void)paste:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } -- (void)select:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } -- (void)selectAll:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } +#pragma mark touch utilities -// these are special additions -- (void)cancel:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } -- (void)commit:(id)sender { [self sendActionToFirstResponder:_cmd from:sender]; } - -// this is a special case, UIKit doesn't normally send anything like this. -// if a UIKit first responder can't handle it, then we'll pass it through to the next responder -// because something else might want to deal with it somewhere else. -- (void)cancelOperation:(id)sender +- (UITouch *)touchForEvent:(NSEvent *)theEvent { - [self sendActionToFirstResponder:@selector(cancel:) from:sender]; + const NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + + UITouch *touch = [[UITouch alloc] init]; + touch.view = [self hitTestUIView:location]; + touch.locationOnScreen = NSPointToCGPoint(location); + touch.timestamp = [theEvent timestamp]; + + return touch; } -// capture the key presses here and turn them into key events which are sent down the UIKit responder chain -// if they come back as unhandled, pass them along the AppKit responder chain. -- (void)keyDown:(NSEvent *)theEvent +- (void)updateTouchLocation:(UITouch *)touch withEvent:(NSEvent *)theEvent { - if (![[UIApplication sharedApplication] _sendKeyboardNSEvent:theEvent fromScreen:_screen]) { - [super keyDown:theEvent]; - } + _touchEvent.touch.locationOnScreen = NSPointToCGPoint([self convertPoint:[theEvent locationInWindow] fromView:nil]); + _touchEvent.touch.timestamp = [theEvent timestamp]; } -- (void)updateTrackingAreas +- (void)cancelTouchesInView:(UIView *)view { - [super updateTrackingAreas]; - [self removeTrackingArea:_trackingArea]; - [_trackingArea release]; - _trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingCursorUpdate|NSTrackingMouseMoved|NSTrackingInVisibleRect|NSTrackingActiveInKeyWindow|NSTrackingMouseEnteredAndExited owner:self userInfo:nil]; - [self addTrackingArea:_trackingArea]; + if (_touchEvent && _touchEvent.touch.phase != UITouchPhaseEnded && _touchEvent.touch.phase != UITouchPhaseCancelled) { + if (!view || [view isDescendantOfView:_touchEvent.touch.view]) { + _touchEvent.touch.phase = UITouchPhaseCancelled; + _touchEvent.touch.timestamp = [NSDate timeIntervalSinceReferenceDate]; + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + [_touchEvent endTouchEvent]; + _touchEvent = nil; + } + } } -- (void)mouseMoved:(NSEvent *)theEvent +- (void)sendStationaryTouches { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + if (_touchEvent && _touchEvent.touch.phase != UITouchPhaseEnded && _touchEvent.touch.phase != UITouchPhaseCancelled) { + _touchEvent.touch.phase = UITouchPhaseStationary; + _touchEvent.touch.timestamp = [NSDate timeIntervalSinceReferenceDate]; + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + } } +#pragma mark pseudo touch handling + - (void)mouseDown:(NSEvent *)theEvent { if ([theEvent modifierFlags] & NSControlKeyMask) { @@ -217,110 +317,271 @@ - (void)mouseDown:(NSEvent *)theEvent // really win anything by overriding that since I'd still need a check in here to prevent that mouseDown: from being // sent to UIKit as a touch. That seems really wrong, IMO. A right click should be independent of a touch event. // soooo.... here we are. Whatever. Seems to work. Don't really like it. - NSEvent *newEvent = [NSEvent mouseEventWithType:NSRightMouseDown location:[theEvent locationInWindow] modifierFlags:0 timestamp:[theEvent timestamp] windowNumber:[theEvent windowNumber] context:[theEvent context] eventNumber:[theEvent eventNumber] clickCount:[theEvent clickCount] pressure:[theEvent pressure]]; - [self rightMouseDown:newEvent]; - } else { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + [self rightMouseDown:[NSEvent mouseEventWithType:NSRightMouseDown location:[theEvent locationInWindow] modifierFlags:0 timestamp:[theEvent timestamp] windowNumber:[theEvent windowNumber] context:[theEvent context] eventNumber:[theEvent eventNumber] clickCount:[theEvent clickCount] pressure:[theEvent pressure]]]; + return; + } + + // this is a special case to cancel any existing touches (as far as the client code is concerned) if the left + // mouse button is pressed mid-gesture. the reason is that sometimes when using a magic mouse a user will intend + // to click but if their finger moves against the surface ever so slightly, it will trigger a touch gesture to + // begin instead. without this, the fact that we're in a touch gesture phase effectively overrules everything + // else and clicks end up not getting registered. I don't think it's right to allow clicks to pass through when + // we're in a gesture state since that'd be somewhat like a multitouch scenerio on an actual iOS device and we + // are not really supporting anything like that at the moment. + if (_touchEvent) { + _touchEvent.touch.phase = UITouchPhaseCancelled; + [self updateTouchLocation:_touchEvent.touch withEvent:theEvent]; + + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + + [_touchEvent endTouchEvent]; + _touchEvent = nil; + } + + if (!_touchEvent) { + _touchEvent = [[UITouchEvent alloc] initWithTouch:[self touchForEvent:theEvent]]; + _touchEvent.touchEventGesture = UITouchEventGestureNone; + _touchEvent.touch.tapCount = [theEvent clickCount]; + + [[UIApplication sharedApplication] sendEvent:_touchEvent]; } } - (void)mouseUp:(NSEvent *)theEvent { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; -} + if (_touchEvent && _touchEvent.touchEventGesture == UITouchEventGestureNone) { + _touchEvent.touch.phase = UITouchPhaseEnded; + [self updateTouchLocation:_touchEvent.touch withEvent:theEvent]; -- (void)mouseDragged:(NSEvent *)theEvent -{ - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; -} - -- (void)rightMouseDown:(NSEvent *)theEvent -{ - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + + [_touchEvent endTouchEvent]; + _touchEvent = nil; + } } -- (void)scrollWheel:(NSEvent *)theEvent +- (void)mouseDragged:(NSEvent *)theEvent { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; -} + if (_touchEvent && _touchEvent.touchEventGesture == UITouchEventGestureNone) { + _touchEvent.touch.phase = UITouchPhaseMoved; + [self updateTouchLocation:_touchEvent.touch withEvent:theEvent]; -- (void)mouseEntered:(NSEvent *)theEvent -{ - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + } } -- (void)mouseExited:(NSEvent *)theEvent -{ - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; -} +#pragma mark touch gestures - (void)beginGestureWithEvent:(NSEvent *)theEvent { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + if (!_touchEvent) { + _touchEvent = [[UITouchEvent alloc] initWithTouch:[self touchForEvent:theEvent]]; + _touchEvent.touchEventGesture = UITouchEventGestureBegin; + + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + } } - (void)endGestureWithEvent:(NSEvent *)theEvent { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + if (_touchEvent && _touchEvent.touchEventGesture != UITouchEventGestureNone) { + _touchEvent.touch.phase = UITouchPhaseEnded; + [self updateTouchLocation:_touchEvent.touch withEvent:theEvent]; + + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + + [_touchEvent endTouchEvent]; + _touchEvent = nil; + } } - (void)rotateWithEvent:(NSEvent *)theEvent { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + if (_touchEvent && (_touchEvent.touchEventGesture == UITouchEventGestureBegin || _touchEvent.touchEventGesture == UITouchEventGestureRotate)) { + _touchEvent.touch.phase = UITouchPhaseMoved; + [self updateTouchLocation:_touchEvent.touch withEvent:theEvent]; + + _touchEvent.touchEventGesture = UITouchEventGestureRotate; + _touchEvent.rotation = [theEvent rotation]; + + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + } } - (void)magnifyWithEvent:(NSEvent *)theEvent { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + if (_touchEvent && (_touchEvent.touchEventGesture == UITouchEventGestureBegin || _touchEvent.touchEventGesture == UITouchEventGesturePinch)) { + _touchEvent.touch.phase = UITouchPhaseMoved; + [self updateTouchLocation:_touchEvent.touch withEvent:theEvent]; + + _touchEvent.touchEventGesture = UITouchEventGesturePinch; + _touchEvent.magnification = [theEvent magnification]; + + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + } } - (void)swipeWithEvent:(NSEvent *)theEvent { - [[UIApplication sharedApplication] _sendMouseNSEvent:theEvent fromScreen:_screen]; + // it seems as if the swipe gesture actually is discrete as far as OSX is concerned and does not occur between gesture begin/end messages + // which is sort of different.. but.. here we go. :) As a result, I'll require there to not be an existing touchEvent in play before a + // swipe gesture is recognized. + + if (!_touchEvent) { + UITouchEvent *swipeEvent = [[UITouchEvent alloc] initWithTouch:[self touchForEvent:theEvent]]; + swipeEvent.touchEventGesture = UITouchEventGestureSwipe; + swipeEvent.translation = CGPointMake([theEvent deltaX], [theEvent deltaY]); + [[UIApplication sharedApplication] sendEvent:swipeEvent]; + [swipeEvent endTouchEvent]; + } } -- (void)_launchApplicationWithDefaultWindow:(UIWindow *)defaultWindow +#pragma mark scroll/pan gesture + +- (void)scrollWheel:(NSEvent *)theEvent { - UIApplication *app = [UIApplication sharedApplication]; - id appDelegate = app.delegate; + double dx, dy; - if ([appDelegate respondsToSelector:@selector(application:didFinishLaunchingWithOptions:)]) { - [appDelegate application:app didFinishLaunchingWithOptions:nil]; - } else if ([appDelegate respondsToSelector:@selector(applicationDidFinishLaunching:)]) { - [appDelegate applicationDidFinishLaunching:app]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidFinishLaunchingNotification object:app]; + CGEventRef cgEvent = [theEvent CGEvent]; + const int64_t isContinious = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventIsContinuous); - if ([appDelegate respondsToSelector:@selector(applicationDidBecomeActive:)]) { - [appDelegate applicationDidBecomeActive:app]; + if (isContinious == 0) { + CGEventSourceRef source = CGEventCreateSourceFromEvent(cgEvent); + double pixelsPerLine; + + if (source) { + pixelsPerLine = CGEventSourceGetPixelsPerLine(source); + CFRelease(source); + } else { + // docs often say things like, "the default is near 10" so it seems reasonable that if the source doesn't work + // for some reason to fetch the pixels per line, then 10 is probably a decent fallback value. :) + pixelsPerLine = 10; + } + + dx = CGEventGetDoubleValueField(cgEvent, kCGScrollWheelEventFixedPtDeltaAxis2) * pixelsPerLine; + dy = CGEventGetDoubleValueField(cgEvent, kCGScrollWheelEventFixedPtDeltaAxis1) * pixelsPerLine; + } else { + dx = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2); + dy = CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); } - [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationDidBecomeActiveNotification object:app]; + CGPoint translation = CGPointMake(-dx, -dy); + + // if this happens within an actual OSX gesture sequence, it is a pan touch gesture event + // if it happens outside of a gesture, it is a normal mouse event instead + // if it somehow happens during any other touch sequence, ignore it (someone might be click-dragging with the mouse and also using a wheel) - defaultWindow.hidden = YES; + if (_touchEvent) { + if (_touchEvent.touchEventGesture == UITouchEventGestureBegin || _touchEvent.touchEventGesture == UITouchEventGesturePan) { + _touchEvent.touch.phase = UITouchPhaseMoved; + [self updateTouchLocation:_touchEvent.touch withEvent:theEvent]; + + _touchEvent.touchEventGesture = UITouchEventGesturePan; + _touchEvent.translation = translation; + + [[UIApplication sharedApplication] sendEvent:_touchEvent]; + } + } else { + UITouchEvent *mouseEvent = [[UITouchEvent alloc] initWithTouch:[self touchForEvent:theEvent]]; + mouseEvent.touchEventGesture = UITouchEventGestureScrollWheel; + mouseEvent.translation = translation; + [[UIApplication sharedApplication] sendEvent:mouseEvent]; + [mouseEvent endTouchEvent]; + } } -- (void)launchApplicationWithDelegate:(id)appDelegate afterDelay:(NSTimeInterval)delay +#pragma mark discrete mouse events + +- (void)rightMouseDown:(NSEvent *)theEvent { - [[UIApplication sharedApplication] setDelegate:appDelegate]; + if (!_touchEvent) { + UITouchEvent *mouseEvent = [[UITouchEvent alloc] initWithTouch:[self touchForEvent:theEvent]]; + mouseEvent.touchEventGesture = UITouchEventGestureRightClick; + mouseEvent.touch.tapCount = [theEvent clickCount]; + [[UIApplication sharedApplication] sendEvent:mouseEvent]; + [mouseEvent endTouchEvent]; + } +} - if (delay) { - UIImage *defaultImage = [UIImage imageNamed:@"Default-Landscape.png"]; - UIImageView *defaultImageView = [[[UIImageView alloc] initWithImage:defaultImage] autorelease]; - defaultImageView.contentMode = UIViewContentModeCenter; +- (void)mouseMoved:(NSEvent *)theEvent +{ + if (!_touchEvent) { + const NSPoint location = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + UIView *currentView = [self hitTestUIView:location]; + UIView *previousView = _mouseMoveTouch.view; - UIWindow *defaultWindow = [(UIWindow *)[UIWindow alloc] initWithFrame:_screen.bounds]; - defaultWindow.userInteractionEnabled = NO; - defaultWindow.screen = _screen; - defaultWindow.backgroundColor = [UIColor blackColor]; // dunno.. - defaultWindow.opaque = YES; - [defaultWindow addSubview:defaultImageView]; - [defaultWindow makeKeyAndVisible]; - [self performSelector:@selector(_launchApplicationWithDefaultWindow:) withObject:defaultWindow afterDelay:delay]; - [defaultWindow release]; + _mouseMoveTouch.timestamp = [theEvent timestamp]; + _mouseMoveTouch.locationOnScreen = NSPointToCGPoint(location); + _mouseMoveTouch.phase = UITouchPhaseMoved; + + if (previousView && previousView != currentView) { + UITouchEvent *moveEvent = [[UITouchEvent alloc] initWithTouch:_mouseMoveTouch]; + moveEvent.touchEventGesture = UITouchEventGestureMouseMove; + [[UIApplication sharedApplication] sendEvent:moveEvent]; + [moveEvent endTouchEvent]; + + UITouchEvent *exitEvent = [[UITouchEvent alloc] initWithTouch:_mouseMoveTouch]; + exitEvent.touchEventGesture = UITouchEventGestureMouseExited; + [[UIApplication sharedApplication] sendEvent:exitEvent]; + [exitEvent endTouchEvent]; + } + + _mouseMoveTouch.view = currentView; + + if (currentView) { + if (currentView != previousView) { + UITouchEvent *enterEvent = [[UITouchEvent alloc] initWithTouch:_mouseMoveTouch]; + enterEvent.touchEventGesture = UITouchEventGestureMouseEntered; + [[UIApplication sharedApplication] sendEvent:enterEvent]; + [enterEvent endTouchEvent]; + } + + UITouchEvent *moveEvent = [[UITouchEvent alloc] initWithTouch:_mouseMoveTouch]; + moveEvent.touchEventGesture = UITouchEventGestureMouseMove; + [[UIApplication sharedApplication] sendEvent:moveEvent]; + [moveEvent endTouchEvent]; + } + } +} + +- (void)mouseEntered:(NSEvent *)theEvent +{ + [self mouseMoved:theEvent]; +} + +- (void)mouseExited:(NSEvent *)theEvent +{ + if (!_touchEvent) { + _mouseMoveTouch.phase = UITouchPhaseMoved; + [self updateTouchLocation:_mouseMoveTouch withEvent:theEvent]; + + UITouchEvent *moveEvent = [[UITouchEvent alloc] initWithTouch:_mouseMoveTouch]; + moveEvent.touchEventGesture = UITouchEventGestureMouseMove; + [[UIApplication sharedApplication] sendEvent:moveEvent]; + [moveEvent endTouchEvent]; + + UITouchEvent *exitEvent = [[UITouchEvent alloc] initWithTouch:_mouseMoveTouch]; + exitEvent.touchEventGesture = UITouchEventGestureMouseExited; + [[UIApplication sharedApplication] sendEvent:exitEvent]; + [exitEvent endTouchEvent]; + + _mouseMoveTouch.view = nil; + } +} + +#pragma keyboard events + +- (void)keyDown:(NSEvent *)theEvent +{ + UIKey *key = [[UIKey alloc] initWithNSEvent:theEvent]; + + // this is not the correct way to handle keys.. iOS 7 finally added a way to handle key commands + // but this was implemented well before that. for now, this gets what we want to happen to happen. + + if (key.action) { + [self doCommandBySelector:key.action]; } else { - [self _launchApplicationWithDefaultWindow:nil]; + [super keyDown:theEvent]; } } diff --git a/UIKit/Classes/UILabel.h b/UIKit/Classes/UILabel.h index 14673cf9..bd76adca 100644 --- a/UIKit/Classes/UILabel.h +++ b/UIKit/Classes/UILabel.h @@ -32,29 +32,15 @@ @class UIFont, UIColor; -@interface UILabel : UIView { -@private - NSString *_text; - UIFont *_font; - UIColor *_textColor; - UIColor *_highlightedTextColor; - UIColor *_shadowColor; - CGSize _shadowOffset; - UITextAlignment _textAlignment; - UILineBreakMode _lineBreakMode; - BOOL _enabled; - NSInteger _numberOfLines; - UIBaselineAdjustment _baselineAdjustment; - BOOL _adjustsFontSizeToFitWidth; - CGFloat _minimumFontSize; - BOOL _highlighted; -} +@interface UILabel : UIView +- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines; +- (void)drawTextInRect:(CGRect)rect; @property (nonatomic, copy) NSString *text; -@property (nonatomic, retain) UIFont *font; -@property (nonatomic, retain) UIColor *textColor; -@property (nonatomic, retain) UIColor *highlightedTextColor; -@property (nonatomic, retain) UIColor *shadowColor; +@property (nonatomic, strong) UIFont *font; +@property (nonatomic, strong) UIColor *textColor; +@property (nonatomic, strong) UIColor *highlightedTextColor; +@property (nonatomic, strong) UIColor *shadowColor; @property (nonatomic) CGSize shadowOffset; @property (nonatomic) UITextAlignment textAlignment; @property (nonatomic) UILineBreakMode lineBreakMode; @@ -64,9 +50,4 @@ @property (nonatomic) BOOL adjustsFontSizeToFitWidth; // not implemented @property (nonatomic) CGFloat minimumFontSize; // not implemented @property (nonatomic, getter=isHighlighted) BOOL highlighted; - - -- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines; -- (void)drawTextInRect:(CGRect)rect; - @end diff --git a/UIKit/Classes/UILabel.m b/UIKit/Classes/UILabel.m index e930cb1c..9c3d26d7 100644 --- a/UIKit/Classes/UILabel.m +++ b/UIKit/Classes/UILabel.m @@ -34,10 +34,6 @@ #import @implementation UILabel -@synthesize text=_text, font=_font, textColor=_textColor, textAlignment=_textAlignment, lineBreakMode=_lineBreakMode, enabled=_enabled; -@synthesize numberOfLines=_numberOfLines, shadowColor=_shadowColor, shadowOffset=_shadowOffset; -@synthesize baselineAdjustment=_baselineAdjustment, adjustsFontSizeToFitWidth=_adjustsFontSizeToFitWidth; -@synthesize highlightedTextColor=_highlightedTextColor, minimumFontSize=_minimumFontSize, highlighted=_highlighted; - (id)initWithFrame:(CGRect)frame { @@ -58,20 +54,10 @@ - (id)initWithFrame:(CGRect)frame return self; } -- (void)dealloc -{ - [_text release]; - [_font release]; - [_textColor release]; - [_shadowColor release]; - [_highlightedTextColor release]; - [super dealloc]; -} - (void)setText:(NSString *)newText { if (_text != newText) { - [_text release]; _text = [newText copy]; [self setNeedsDisplay]; } @@ -82,8 +68,7 @@ - (void)setFont:(UIFont *)newFont assert(newFont != nil); if (newFont != _font) { - [_font release]; - _font = [newFont retain]; + _font = newFont; [self setNeedsDisplay]; } } @@ -91,8 +76,7 @@ - (void)setFont:(UIFont *)newFont - (void)setTextColor:(UIColor *)newColor { if (newColor != _textColor) { - [_textColor release]; - _textColor = [newColor retain]; + _textColor = newColor; [self setNeedsDisplay]; } } @@ -100,8 +84,7 @@ - (void)setTextColor:(UIColor *)newColor - (void)setShadowColor:(UIColor *)newColor { if (newColor != _shadowColor) { - [_shadowColor release]; - _shadowColor = [newColor retain]; + _shadowColor = newColor; [self setNeedsDisplay]; } } diff --git a/UIKit/Classes/UILongPressGestureRecognizer.h b/UIKit/Classes/UILongPressGestureRecognizer.h index 52cfc1ca..be106126 100644 --- a/UIKit/Classes/UILongPressGestureRecognizer.h +++ b/UIKit/Classes/UILongPressGestureRecognizer.h @@ -34,19 +34,16 @@ // and it doesn't worry about allowableMovement and the other parameters that the regular long // press would normally need to be worried about. -@interface UILongPressGestureRecognizer : UIGestureRecognizer { -@private - CFTimeInterval _minimumPressDuration; - CGFloat _allowableMovement; - NSUInteger _numberOfTapsRequired; - NSInteger _numberOfTouchesRequired; - CGPoint _beginLocation; - BOOL _waiting; -} +// Note that technically the long press gesture is continuous but a right click is discrete in Chameleon, +// so this is sort of a hack as it immediately switches to UIGestureRecognizerStateBegan in that case and +// ends up never switching to UIGestureRecognizerStateEnded. Since the right click "gesture" is discrete, +// it ends up getting aborted/reset before that happens. So if you want your long press recognizer to work +// with right clicks, make sure you take action when the state switches to UIGestureRecognizerStateBegan +// instead of UIGestureRecognizerStateEnded. +@interface UILongPressGestureRecognizer : UIGestureRecognizer @property (nonatomic) CFTimeInterval minimumPressDuration; @property (nonatomic) CGFloat allowableMovement; @property (nonatomic) NSUInteger numberOfTapsRequired; @property (nonatomic) NSInteger numberOfTouchesRequired; - @end diff --git a/UIKit/Classes/UILongPressGestureRecognizer.m b/UIKit/Classes/UILongPressGestureRecognizer.m index 6eabf1a4..069af03c 100644 --- a/UIKit/Classes/UILongPressGestureRecognizer.m +++ b/UIKit/Classes/UILongPressGestureRecognizer.m @@ -29,8 +29,9 @@ #import "UILongPressGestureRecognizer.h" #import "UIGestureRecognizerSubclass.h" -#import "UITouch+UIPrivate.h" -#import "UIEvent.h" +#import "UITouchEvent.h" +#import "UITouch.h" +#import "UIApplicationAppKitIntegration.h" static CGFloat DistanceBetweenTwoPoints(CGPoint A, CGPoint B) { @@ -39,9 +40,10 @@ static CGFloat DistanceBetweenTwoPoints(CGPoint A, CGPoint B) return sqrtf((a*a) + (b*b)); } -@implementation UILongPressGestureRecognizer -@synthesize minimumPressDuration=_minimumPressDuration, allowableMovement=_allowableMovement, numberOfTapsRequired=_numberOfTapsRequired; -@synthesize numberOfTouchesRequired=_numberOfTouchesRequired; +@implementation UILongPressGestureRecognizer { + CGPoint _beginLocation; + BOOL _waiting; +} - (id)initWithTarget:(id)target action:(SEL)action { @@ -54,28 +56,12 @@ - (id)initWithTarget:(id)target action:(SEL)action return self; } -- (void)_discreteGestures:(NSSet *)touches withEvent:(UIEvent *)event -{ - UITouch *touch = [[event touchesForGestureRecognizer:self] anyObject]; - - if (self.state == UIGestureRecognizerStatePossible && [touch _gesture] == _UITouchDiscreteGestureRightClick) { - self.state = UIGestureRecognizerStateBegan; - [self performSelector:@selector(_endFakeContinuousGesture) withObject:nil afterDelay:0]; - } -} - -- (void)_endFakeContinuousGesture -{ - if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) { - self.state = UIGestureRecognizerStateEnded; - } -} - - (void)_beginGesture { _waiting = NO; if (self.state == UIGestureRecognizerStatePossible) { self.state = UIGestureRecognizerStateBegan; + UIApplicationSendStationaryTouches(); } } @@ -83,32 +69,42 @@ - (void)_cancelWaiting { if (_waiting) { _waiting = NO; - [isa cancelPreviousPerformRequestsWithTarget:self selector:@selector(_beginGesture) object:nil]; + [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(_beginGesture) object:nil]; } } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - UITouch *touch = [[event touchesForGestureRecognizer:self] anyObject]; - - if (!_waiting && self.state == UIGestureRecognizerStatePossible && touch.tapCount >= self.numberOfTapsRequired) { - _beginLocation = [touch locationInView:self.view]; - _waiting = YES; - [self performSelector:@selector(_beginGesture) withObject:nil afterDelay:self.minimumPressDuration]; + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + + if (touchEvent.touchEventGesture == UITouchEventGestureRightClick) { + self.state = UIGestureRecognizerStateBegan; + } else if (touchEvent.touchEventGesture == UITouchEventGestureNone) { + if (!_waiting && self.state == UIGestureRecognizerStatePossible && touchEvent.touch.tapCount >= self.numberOfTapsRequired) { + _beginLocation = [touchEvent.touch locationInView:self.view]; + _waiting = YES; + [self performSelector:@selector(_beginGesture) withObject:nil afterDelay:self.minimumPressDuration]; + } + } else { + self.state = UIGestureRecognizerStateFailed; + } } } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + UITouch *touch = [touches anyObject]; + const CGFloat distance = DistanceBetweenTwoPoints([touch locationInView:self.view], _beginLocation); + if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) { - UITouch *touch = [[event touchesForGestureRecognizer:self] anyObject]; - const CGFloat distance = DistanceBetweenTwoPoints([touch locationInView:self.view], _beginLocation); - if (distance <= self.allowableMovement) { self.state = UIGestureRecognizerStateChanged; } else { self.state = UIGestureRecognizerStateCancelled; } + } else if (self.state == UIGestureRecognizerStatePossible && distance > self.allowableMovement) { + self.state = UIGestureRecognizerStateFailed; } } @@ -130,4 +126,10 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event } } +- (void)reset +{ + [self _cancelWaiting]; + [super reset]; +} + @end diff --git a/UIKit/Classes/UIMenuController.h b/UIKit/Classes/UIMenuController.h index db536736..5130390c 100644 --- a/UIKit/Classes/UIMenuController.h +++ b/UIKit/Classes/UIMenuController.h @@ -35,19 +35,9 @@ extern NSString *const UIMenuControllerWillHideMenuNotification; extern NSString *const UIMenuControllerDidHideMenuNotification; extern NSString *const UIMenuControllerMenuFrameDidChangeNotification; -@class UIView, UIWindow; - -@interface UIMenuController : NSObject { -@private - NSArray *_menuItems; - NSMutableArray *_enabledMenuItems; - id _menu; - CGRect _menuFrame; - CGPoint _menuLocation; - BOOL _rightAlignMenu; - UIWindow *_window; -} +@class UIView; +@interface UIMenuController : NSObject + (UIMenuController *)sharedMenuController; - (void)setMenuVisible:(BOOL)menuVisible animated:(BOOL)animated; @@ -62,5 +52,4 @@ extern NSString *const UIMenuControllerMenuFrameDidChangeNotification; // the menu is made visible. I have no intenstively tested what the real UIKit does in all the possible // situations. You have been warned. @property (nonatomic, readonly) CGRect menuFrame; - @end diff --git a/UIKit/Classes/UIMenuController.m b/UIKit/Classes/UIMenuController.m index d5c0637c..410f50d8 100644 --- a/UIKit/Classes/UIMenuController.m +++ b/UIKit/Classes/UIMenuController.m @@ -28,7 +28,7 @@ */ #import "UIMenuController.h" -#import "UIApplication+UIPrivate.h" +#import "UIApplicationAppKitIntegration.h" #import "UIWindow+UIPrivate.h" #import "UIScreenAppKitIntegration.h" #import "UIKitView.h" @@ -46,8 +46,13 @@ @interface UIMenuController () @end -@implementation UIMenuController -@synthesize menuItems=_menuItems, menuFrame=_menuFrame; +@implementation UIMenuController { + NSMutableArray *_enabledMenuItems; + NSMenu *_menu; + CGPoint _menuLocation; + BOOL _rightAlignMenu; + UIWindow *_window; +} + (UIMenuController *)sharedMenuController { @@ -61,12 +66,12 @@ + (NSArray *)_defaultMenuItems if (!items) { items = [[NSArray alloc] initWithObjects: - [[[UIMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:)] autorelease], - [[[UIMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:)] autorelease], - [[[UIMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:)] autorelease], - [[[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(delete:)] autorelease], - [[[UIMenuItem alloc] initWithTitle:@"Select" action:@selector(select:)] autorelease], - [[[UIMenuItem alloc] initWithTitle:@"Select All" action:@selector(selectAll:)] autorelease], + [[UIMenuItem alloc] initWithTitle:@"Cut" action:@selector(cut:)], + [[UIMenuItem alloc] initWithTitle:@"Copy" action:@selector(copy:)], + [[UIMenuItem alloc] initWithTitle:@"Paste" action:@selector(paste:)], + [[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(delete:)], + [[UIMenuItem alloc] initWithTitle:@"Select" action:@selector(select:)], + [[UIMenuItem alloc] initWithTitle:@"Select All" action:@selector(selectAll:)], nil]; } @@ -84,11 +89,7 @@ - (id)init - (void)dealloc { - [_menuItems release]; - [_enabledMenuItems release]; [_menu cancelTracking]; // this should never really happen since the controller is pretty much always a singleton, but... whatever. - [_menu release]; - [super dealloc]; } - (BOOL)isMenuVisible @@ -114,7 +115,6 @@ - (void)setMenuVisible:(BOOL)menuVisible animated:(BOOL)animated [theItem setTarget:self]; [theItem setRepresentedObject:item]; [_menu addItem:theItem]; - [theItem release]; } _menuFrame.size = NSSizeToCGSize([_menu size]); @@ -141,7 +141,6 @@ - (void)setMenuVisible:(BOOL)menuVisible animated:(BOOL)animated } else { [_menu cancelTrackingWithoutAnimation]; } - [_menu release]; _menu = nil; } } @@ -194,7 +193,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]; @@ -210,10 +209,10 @@ - (void)update - (void)_presentMenu { if (_menu && _window) { - NSView *theNSView = [_window.screen UIKitView]; + NSView *theNSView = _window.screen.UIKitView; if (theNSView) { [_menu popUpMenuPositioningItem:nil atLocation:NSPointFromCGPoint(_menuFrame.origin) inView:theNSView]; - [[UIApplication sharedApplication] _cancelTouches]; + UIApplicationInterruptTouchesInView(nil); } } } @@ -244,7 +243,6 @@ - (void)_didSelectMenuItem:(NSMenuItem *)sender - (void)menuDidClose:(NSMenu *)menu { if (menu == _menu) { - [_menu release]; _menu = nil; } } diff --git a/UIKit/Classes/UIMenuItem.h b/UIKit/Classes/UIMenuItem.h index 81b35639..841a1dea 100644 --- a/UIKit/Classes/UIMenuItem.h +++ b/UIKit/Classes/UIMenuItem.h @@ -29,15 +29,9 @@ #import -@interface UIMenuItem : NSObject { -@private - SEL _action; - NSString *_title; -} - +@interface UIMenuItem : NSObject - (id)initWithTitle:(NSString *)title action:(SEL)action; @property SEL action; @property (copy) NSString *title; - @end diff --git a/UIKit/Classes/UIMenuItem.m b/UIKit/Classes/UIMenuItem.m index 7fbfe9a0..4ee3ab8c 100644 --- a/UIKit/Classes/UIMenuItem.m +++ b/UIKit/Classes/UIMenuItem.m @@ -30,7 +30,6 @@ #import "UIMenuItem.h" @implementation UIMenuItem -@synthesize action=_action, title=_title; - (id)initWithTitle:(NSString *)title action:(SEL)action { @@ -41,10 +40,4 @@ - (id)initWithTitle:(NSString *)title action:(SEL)action return self; } -- (void)dealloc -{ - [_title release]; - [super dealloc]; -} - @end diff --git a/UIKit/Classes/UIViewController+UIPrivate.h b/UIKit/Classes/UINSApplicationDelegate.h similarity index 88% rename from UIKit/Classes/UIViewController+UIPrivate.h rename to UIKit/Classes/UINSApplicationDelegate.h index 6b26e8bd..6f4addd5 100644 --- a/UIKit/Classes/UIViewController+UIPrivate.h +++ b/UIKit/Classes/UINSApplicationDelegate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -27,8 +27,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIViewController.h" +#import -@interface UIViewController (UIPrivate) -- (void)_setParentViewController:(UIViewController *)controller; +@interface UINSApplicationDelegate : NSObject @end diff --git a/UIKit/Classes/UIViewBlockAnimationDelegate.h b/UIKit/Classes/UINSApplicationDelegate.m similarity index 60% rename from UIKit/Classes/UIViewBlockAnimationDelegate.h rename to UIKit/Classes/UINSApplicationDelegate.m index c410a6aa..c0a832de 100644 --- a/UIKit/Classes/UIViewBlockAnimationDelegate.h +++ b/UIKit/Classes/UINSApplicationDelegate.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -27,16 +27,27 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import +#import "UINSApplicationDelegate.h" +#import "UIApplicationAppKitIntegration.h" -@interface UIViewBlockAnimationDelegate : NSObject { - void (^_completion)(BOOL finished); - BOOL _ignoreInteractionEvents; +@implementation UINSApplicationDelegate + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + return [[UIApplication sharedApplication] terminateApplicationBeforeDate:[NSDate dateWithTimeIntervalSinceNow:30]]; } -@property (nonatomic, copy) void (^completion)(BOOL finished); -@property (nonatomic, assign) BOOL ignoreInteractionEvents; +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; +} -- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished; +- (void)handleURLEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent +{ + NSURL* url = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]]; + UIApplication *app = [UIApplication sharedApplication]; + + [app.delegate application:app openURL:url sourceApplication:nil annotation:nil]; +} @end diff --git a/UIKit/Classes/UINSClipView.h b/UIKit/Classes/UINSClipView.h index 619c5cd1..5d30546c 100644 --- a/UIKit/Classes/UINSClipView.h +++ b/UIKit/Classes/UINSClipView.h @@ -31,9 +31,7 @@ @class UIScrollView; -@interface UINSClipView : NSClipView { - UIScrollView *parentView; -} +@interface UINSClipView : NSClipView - (id)initWithFrame:(NSRect)frame parentView:(UIScrollView *)aView; diff --git a/UIKit/Classes/UINSClipView.m b/UIKit/Classes/UINSClipView.m index f9100af0..53fa8e4a 100644 --- a/UIKit/Classes/UINSClipView.m +++ b/UIKit/Classes/UINSClipView.m @@ -30,18 +30,19 @@ #import "UINSClipView.h" #import "UIScrollView+UIPrivate.h" #import "UIWindow.h" -#import "UIScreen+UIPrivate.h" #import "UIScreenAppKitIntegration.h" #import "UIKitView.h" #import -@implementation UINSClipView +@implementation UINSClipView { + UIScrollView *_parentView; +} - (id)initWithFrame:(NSRect)frame parentView:(UIScrollView *)aView { if ((self=[super initWithFrame:frame])) { - parentView = aView; + _parentView = aView; [self setDrawsBackground:NO]; [self setCopiesOnScroll:NO]; [self setWantsLayer:YES]; @@ -62,13 +63,13 @@ - (BOOL)isOpaque - (void)scrollWheel:(NSEvent *)event { - if (parentView.scrollEnabled) { + if (_parentView.scrollEnabled) { NSPoint offset = [self bounds].origin; offset.x -= [event deltaX]; offset.y -= [event deltaY]; - [parentView _quickFlashScrollIndicators]; - [parentView setContentOffset:NSPointToCGPoint(offset) animated:NO]; + [_parentView _quickFlashScrollIndicators]; + [_parentView setContentOffset:NSPointToCGPoint(offset) animated:NO]; } else { [super scrollWheel:event]; } @@ -77,19 +78,19 @@ - (void)scrollWheel:(NSEvent *)event - (void)viewDidMoveToSuperview { [super viewDidMoveToSuperview]; - [parentView setNeedsLayout]; + [_parentView setNeedsLayout]; } - (void)viewWillDraw { - [parentView setNeedsLayout]; + [_parentView setNeedsLayout]; [super viewWillDraw]; } - (void)setFrame:(NSRect)frame { [super setFrame:frame]; - [parentView setNeedsLayout]; + [_parentView setNeedsLayout]; } // this is used to fake out AppKit when the UIView that "owns" this NSView's layer is actually *behind* another UIView. Since the NSViews are @@ -100,15 +101,11 @@ - (NSView *)hitTest:(NSPoint)aPoint NSView *hitNSView = [super hitTest:aPoint]; if (hitNSView) { - UIScreen *screen = parentView.window.screen; + UIScreen *screen = _parentView.window.screen; BOOL didHitUIView = NO; if (screen) { - if (![[screen UIKitView] isFlipped]) { - aPoint.y = screen.bounds.size.height - aPoint.y - 1; - } - - didHitUIView = (parentView == [screen _hitTest:NSPointToCGPoint(aPoint) event:nil]); + didHitUIView = (_parentView == [screen.UIKitView hitTestUIView:aPoint]); } if (!didHitUIView) { diff --git a/UIKit/Classes/UINavigationBar+UIPrivate.h b/UIKit/Classes/UINSResponderShim.h similarity index 54% rename from UIKit/Classes/UINavigationBar+UIPrivate.h rename to UIKit/Classes/UINSResponderShim.h index ebb74e6b..5b352572 100644 --- a/UIKit/Classes/UINavigationBar+UIPrivate.h +++ b/UIKit/Classes/UINSResponderShim.h @@ -1,11 +1,5 @@ -// -// UINavigationBar+UIPrivate.h -// UIKit -// -// Created by Jim Dovey on 11-03-22. -// /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -33,8 +27,26 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UINavigationBar.h" +#import +#import + +// when the shim gets asked if it can respond to a method, it asks the delegate's responder if it can respond +// to it or not +// +// if the shim is sent a message that it needs to forward, it uses the delegate's responder as a starting point +// and walks the responder chain until it finds the responder to send it to. if it turns out the responder +// returned cannot respond to the selector, it eventually ends up with a doesNotRecognizeSelector exception. +// +// the shim also implements NSUserInterfaceValidations by sending it's responder -canPerformAction:withSender: +// messages for proposed actions. if the responder says it can perform the action, it validates. this allows +// native OSX menus and toolbars to reach down into the UIKit responder chain and enable/disable accordingly. + +@class UINSResponderShim, UIResponder; + +@protocol UINSResponderShimDelegate +- (UIResponder *)responderForResponderShim:(UINSResponderShim *)shim; +@end -@interface UINavigationBar (UIPrivate) -- (void)_updateNavigationItem:(UINavigationItem *)item animated:(BOOL)animated; -@end \ No newline at end of file +@interface UINSResponderShim : NSResponder +@property (nonatomic, assign) id delegate; +@end diff --git a/UIKit/Classes/UINSResponderShim.m b/UIKit/Classes/UINSResponderShim.m new file mode 100644 index 00000000..54f63d2d --- /dev/null +++ b/UIKit/Classes/UINSResponderShim.m @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, 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. + */ + +#import "UINSResponderShim.h" +#import "UIResponder.h" + +@implementation UINSResponderShim + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector withResponder:(UIResponder *)responder +{ + for (; responder != nil; responder = [responder nextResponder]) { + NSMethodSignature *sig = [responder methodSignatureForSelector:aSelector]; + + if (sig) { + return sig; + } + } + + return nil; +} + +- (BOOL)respondsToSelector:(SEL)aSelector +{ + if ([super respondsToSelector:aSelector]) { + return YES; + } + + return ([self methodSignatureForSelector:aSelector withResponder:[self.delegate responderForResponderShim:self]] != nil); +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + NSMethodSignature *sig = [super methodSignatureForSelector:aSelector]; + + if (!sig) { + sig = [self methodSignatureForSelector:aSelector withResponder:[self.delegate responderForResponderShim:self]]; + } + + return sig; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation +{ + for (UIResponder *responder = [self.delegate responderForResponderShim:self]; responder != nil; responder = [responder nextResponder]) { + if ([responder respondsToSelector:[anInvocation selector]]) { + [anInvocation invokeWithTarget:responder]; + return; + } + } + + [super forwardInvocation:anInvocation]; +} + +- (BOOL)validateUserInterfaceItem:(id < NSValidatedUserInterfaceItem >)anItem +{ + return [[self.delegate responderForResponderShim:self] canPerformAction:[anItem action] withSender:nil]; +} + +@end diff --git a/UIKit/Classes/UINavigationBar.h b/UIKit/Classes/UINavigationBar.h index f7b7d5a1..30be78a5 100644 --- a/UIKit/Classes/UINavigationBar.h +++ b/UIKit/Classes/UINavigationBar.h @@ -40,39 +40,21 @@ - (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item; @end -@interface UINavigationBar : UIView { -@private - NSMutableArray *_navStack; - UIColor *_tintColor; - __unsafe_unretained id _delegate; - - UIView *_leftView; - UIView *_centerView; - UIView *_rightView; - - struct { - unsigned shouldPushItem : 1; - unsigned didPushItem : 1; - unsigned shouldPopItem : 1; - unsigned didPopItem : 1; - } _delegateHas; - - // ideally this should share the same memory as the above flags structure... - struct { - unsigned reloadItem : 1; - unsigned __RESERVED__ : 31; - } _navigationBarFlags; -} - +@interface UINavigationBar : UIView - (void)setItems:(NSArray *)items animated:(BOOL)animated; - (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated; - (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated; -@property (nonatomic, assign) UIBarStyle barStyle; -@property (nonatomic, retain) UIColor *tintColor; -@property (nonatomic, readonly, retain) UINavigationItem *topItem; -@property (nonatomic, readonly, retain) UINavigationItem *backItem; -@property (nonatomic, copy) NSArray *items; -@property (nonatomic, assign) id delegate; +- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics; +- (UIImage *)backgroundImageForBarMetrics:(UIBarMetrics)barMetrics; +- (void)setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics; +- (CGFloat)titleVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics; +@property (nonatomic, assign) id delegate; +@property (nonatomic, copy) NSArray *items; +@property (nonatomic, assign) UIBarStyle barStyle; +@property (nonatomic, readonly, strong) UINavigationItem *topItem; +@property (nonatomic, readonly, strong) UINavigationItem *backItem; +@property (nonatomic, strong) UIColor *tintColor; +@property (nonatomic, copy) NSDictionary *titleTextAttributes; @end diff --git a/UIKit/Classes/UINavigationBar.m b/UIKit/Classes/UINavigationBar.m index 226deeb4..e79a13f7 100644 --- a/UIKit/Classes/UINavigationBar.m +++ b/UIKit/Classes/UINavigationBar.m @@ -28,32 +28,43 @@ */ #import "UINavigationBar.h" -#import "UINavigationBar+UIPrivate.h" #import "UIGraphics.h" #import "UIColor.h" #import "UILabel.h" -#import "UINavigationItem.h" #import "UINavigationItem+UIPrivate.h" #import "UIFont.h" #import "UIImage+UIPrivate.h" #import "UIBarButtonItem.h" #import "UIButton.h" -static const UIEdgeInsets kButtonEdgeInsets = {0,0,0,0}; +static const UIEdgeInsets kButtonEdgeInsets = {2,2,2,2}; static const CGFloat kMinButtonWidth = 30; static const CGFloat kMaxButtonWidth = 200; static const CGFloat kMaxButtonHeight = 24; +static const CGFloat kBarHeight = 28; static const NSTimeInterval kAnimationDuration = 0.33; -typedef enum { +typedef NS_ENUM(NSInteger, _UINavigationBarTransition) { + _UINavigationBarTransitionNone = 0, _UINavigationBarTransitionPush, _UINavigationBarTransitionPop, - _UINavigationBarTransitionReload // explicitly tag reloads from changed UINavigationItem data -} _UINavigationBarTransition; +}; -@implementation UINavigationBar -@synthesize tintColor=_tintColor, delegate=_delegate, items=_navStack; +@implementation UINavigationBar { + NSMutableArray *_navStack; + + UIView *_leftView; + UIView *_centerView; + UIView *_rightView; + + struct { + unsigned shouldPushItem : 1; + unsigned didPushItem : 1; + unsigned shouldPopItem : 1; + unsigned didPopItem : 1; + } _delegateHas; +} + (void)_setBarButtonSize:(UIView *)view { @@ -64,14 +75,12 @@ + (void)_setBarButtonSize:(UIView *)view view.frame = frame; } -+ (UIButton *)_backButtonWithBarButtonItem:(UIBarButtonItem *)item ++ (UIButton *)_backButtonWithTitle:(NSString *)title { - if (!item) return nil; - UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom]; [backButton setBackgroundImage:[UIImage _backButtonImage] forState:UIControlStateNormal]; [backButton setBackgroundImage:[UIImage _highlightedBackButtonImage] forState:UIControlStateHighlighted]; - [backButton setTitle:item.title forState:UIControlStateNormal]; + [backButton setTitle:(title ?: @"Back") forState:UIControlStateNormal]; backButton.titleLabel.font = [UIFont systemFontOfSize:11]; backButton.contentEdgeInsets = UIEdgeInsetsMake(0,15,0,7); [backButton addTarget:nil action:@selector(_backButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; @@ -102,19 +111,21 @@ + (UIView *)_viewWithBarButtonItem:(UIBarButtonItem *)item - (id)initWithFrame:(CGRect)frame { + frame.size.height = kBarHeight; + if ((self=[super initWithFrame:frame])) { _navStack = [[NSMutableArray alloc] init]; - self.tintColor = [UIColor colorWithRed:21/255.f green:21/255.f blue:25/255.f alpha:1]; + _barStyle = UIBarStyleDefault; + _tintColor = [UIColor colorWithRed:21/255.f green:21/255.f blue:25/255.f alpha:1]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_navigationItemDidChange:) name:UINavigationItemDidChange object:nil]; } return self; } - (void)dealloc { - [self.topItem _setNavigationBar: nil]; - [_navStack release]; - [_tintColor release]; - [super dealloc]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)setDelegate:(id)newDelegate @@ -141,11 +152,6 @@ - (void)_backButtonTapped:(id)sender [self popNavigationItemAnimated:YES]; } -- (void)_removeAnimatedViews:(NSArray *)views -{ - [views makeObjectsPerformSelector:@selector(removeFromSuperview)]; -} - - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated:(BOOL)animated { { @@ -164,12 +170,6 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: moveLeftBy *= -1.f; } - [UIView animateWithDuration:kAnimationDuration - animations:^(void) { - if (_leftView) _leftView.frame = CGRectOffset(_leftView.frame, moveLeftBy, 0); - if (_centerView) _centerView.frame = CGRectOffset(_centerView.frame, moveCenterBy, 0); - }]; - [UIView animateWithDuration:kAnimationDuration * 0.8 delay:kAnimationDuration * 0.2 options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionNone @@ -180,12 +180,17 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: } completion:NULL]; - [self performSelector:@selector(_removeAnimatedViews:) withObject:previousViews afterDelay:kAnimationDuration]; + [UIView animateWithDuration:kAnimationDuration + animations:^(void) { + if (_leftView) _leftView.frame = CGRectOffset(_leftView.frame, moveLeftBy, 0); + if (_centerView) _centerView.frame = CGRectOffset(_centerView.frame, moveCenterBy, 0); + } + completion:^(BOOL finished) { + [previousViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + }]; } else { - [self _removeAnimatedViews:previousViews]; + [previousViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; } - - [previousViews release]; } UINavigationItem *topItem = self.topItem; @@ -193,17 +198,13 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: if (topItem) { UINavigationItem *backItem = self.backItem; - // update weak references - [backItem _setNavigationBar: nil]; - [topItem _setNavigationBar: self]; - CGRect leftFrame = CGRectZero; CGRect rightFrame = CGRectZero; if (backItem) { - _leftView = [isa _backButtonWithBarButtonItem:backItem.backBarButtonItem]; + _leftView = [[self class] _backButtonWithTitle:backItem.backBarButtonItem.title ?: backItem.title]; } else { - _leftView = [isa _viewWithBarButtonItem:topItem.leftBarButtonItem]; + _leftView = [[self class] _viewWithBarButtonItem:topItem.leftBarButtonItem]; } if (_leftView) { @@ -213,7 +214,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; @@ -227,7 +228,7 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: _centerView = topItem.titleView; if (!_centerView) { - UILabel *titleLabel = [[[UILabel alloc] init] autorelease]; + UILabel *titleLabel = [[UILabel alloc] init]; titleLabel.text = topItem.title; titleLabel.textAlignment = UITextAlignmentCenter; titleLabel.backgroundColor = [UIColor clearColor]; @@ -236,10 +237,28 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: _centerView = titleLabel; } - const CGFloat centerPadding = MAX(leftFrame.size.width, rightFrame.size.width); + CGRect centerFrame = CGRectZero; + + centerFrame.origin.y = kButtonEdgeInsets.top; + centerFrame.size.height = kMaxButtonHeight; + + if (_leftView && _rightView) { + centerFrame.origin.x = CGRectGetMaxX(leftFrame) + kButtonEdgeInsets.left; + centerFrame.size.width = CGRectGetMinX(rightFrame) - kButtonEdgeInsets.right - centerFrame.origin.x; + } else if (_leftView) { + centerFrame.origin.x = CGRectGetMaxX(leftFrame) + kButtonEdgeInsets.left; + centerFrame.size.width = CGRectGetWidth(self.bounds) - centerFrame.origin.x - CGRectGetWidth(leftFrame) - kButtonEdgeInsets.right - kButtonEdgeInsets.right; + } else if (_rightView) { + centerFrame.origin.x = CGRectGetWidth(rightFrame) + kButtonEdgeInsets.left + kButtonEdgeInsets.left; + centerFrame.size.width = CGRectGetWidth(self.bounds) - centerFrame.origin.x - CGRectGetWidth(rightFrame) - kButtonEdgeInsets.right - kButtonEdgeInsets.right; + } else { + centerFrame.origin.x = kButtonEdgeInsets.left; + centerFrame.size.width = CGRectGetWidth(self.bounds) - kButtonEdgeInsets.left - kButtonEdgeInsets.right; + } + _centerView.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _centerView.frame = CGRectMake(kButtonEdgeInsets.left+centerPadding,kButtonEdgeInsets.top,self.bounds.size.width-kButtonEdgeInsets.right-kButtonEdgeInsets.left-centerPadding-centerPadding,kMaxButtonHeight); - [self addSubview:_centerView]; + _centerView.frame = centerFrame; + [self insertSubview:_centerView atIndex:0]; if (animated) { CGFloat moveCenterBy = self.bounds.size.width - ((_centerView)? _centerView.frame.origin.x : 0); @@ -284,8 +303,7 @@ - (void)_setViewsWithTransition:(_UINavigationBarTransition)transition animated: - (void)setTintColor:(UIColor *)newColor { if (newColor != _tintColor) { - [_tintColor release]; - _tintColor = [newColor retain]; + _tintColor = newColor; [self setNeedsDisplay]; } } @@ -304,15 +322,6 @@ - (void)setItems:(NSArray *)items [self setItems:items animated:NO]; } -- (UIBarStyle)barStyle -{ - return UIBarStyleDefault; -} - -- (void)setBarStyle:(UIBarStyle)barStyle -{ -} - - (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated { BOOL shouldPush = YES; @@ -343,7 +352,6 @@ - (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated } if (shouldPop) { - [previousItem retain]; [_navStack removeObject:previousItem]; [self _setViewsWithTransition:_UINavigationBarTransitionPop animated:animated]; @@ -351,39 +359,21 @@ - (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated [_delegate navigationBar:self didPopItem:previousItem]; } - return [previousItem autorelease]; + return previousItem; } } return nil; } -- (void)_updateNavigationItem:(UINavigationItem *)item animated:(BOOL)animated // ignored for now +- (void)_navigationItemDidChange:(NSNotification *)note { - // let's sanity-check that the item is supposed to be talking to us - if (item != self.topItem) { - [item _setNavigationBar:nil]; - return; - } - - // this is going to remove & re-add all the item views. Not ideal, but simple enough that it's worth profiling. - // next step is to add animation support-- that will require changing _setViewsWithTransition:animated: - // such that it won't perform any coordinate translations, only fade in/out - - // don't just fire the damned thing-- set a flag & mark as needing layout - if (_navigationBarFlags.reloadItem == 0) { - _navigationBarFlags.reloadItem = 1; - [self setNeedsLayout]; - } -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - if (_navigationBarFlags.reloadItem) { - _navigationBarFlags.reloadItem = 0; - [self _setViewsWithTransition:_UINavigationBarTransitionReload animated:NO]; + if ([note object] == self.topItem || [note object] == self.backItem) { + // this is going to remove & re-add all the item views. Not ideal, but simple enough that it's worth profiling. + // next step is to add animation support-- that will require changing _setViewsWithTransition:animated: + // such that it won't perform any coordinate translations, only fade in/out + + [self _setViewsWithTransition:_UINavigationBarTransitionNone animated:NO]; } } @@ -395,8 +385,32 @@ - (void)drawRect:(CGRect)rect // so that it actually doesn "tint" the image instead of define it. That'd probably work better with the bottom line coloring and stuff, too, but // for now hardcoding stuff works well enough. - [_tintColor setFill]; + [self.tintColor setFill]; UIRectFill(bounds); } +- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics +{ +} + +- (UIImage *)backgroundImageForBarMetrics:(UIBarMetrics)barMetrics +{ + return nil; +} + +- (void)setTitleVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics +{ +} + +- (CGFloat)titleVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics +{ + return 0; +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + size.height = kBarHeight; + return size; +} + @end diff --git a/UIKit/Classes/UINavigationController.h b/UIKit/Classes/UINavigationController.h index fb9813c5..882a4a6f 100644 --- a/UIKit/Classes/UINavigationController.h +++ b/UIKit/Classes/UINavigationController.h @@ -37,51 +37,22 @@ - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated; @end -typedef enum { - _UINavigationControllerVisibleControllerTransitionNone = 0, - _UINavigationControllerVisibleControllerTransitionPushAnimated, - _UINavigationControllerVisibleControllerTransitionPopAnimated -} _UINavigationControllerVisibleControllerTransition; - -@interface UINavigationController : UIViewController { -@private - UINavigationBar *_navigationBar; - UIToolbar *_toolbar; - NSMutableArray *_viewControllers; - __unsafe_unretained id _delegate; - BOOL _toolbarHidden; - BOOL _navigationBarHidden; - - BOOL _visibleViewControllerNeedsUpdate; - _UINavigationControllerVisibleControllerTransition _visibleViewControllerTransition; - UIViewController *_visibleViewController; - - struct { - unsigned didShowViewController : 1; - unsigned willShowViewController : 1; - } _delegateHas; -} - +@interface UINavigationController : UIViewController - (id)initWithRootViewController:(UIViewController *)rootViewController; - - (void)setViewControllers:(NSArray *)newViewControllers animated:(BOOL)animated; - - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; - (UIViewController *)popViewControllerAnimated:(BOOL)animated; - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated; - - (void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated; // toolbar support is not really implemented yet - - (void)setNavigationBarHidden:(BOOL)navigationBarHidden animated:(BOOL)animated; // doesn't animate yet @property (nonatomic, copy) NSArray *viewControllers; -@property (nonatomic, readonly, retain) UIViewController *visibleViewController; +@property (nonatomic, readonly, strong) UIViewController *visibleViewController; @property (nonatomic, readonly) UINavigationBar *navigationBar; @property (nonatomic, readonly) UIToolbar *toolbar; // toolbar support is not really implemented yet @property (nonatomic, assign) id delegate; -@property (nonatomic, readonly, retain) UIViewController *topViewController; -@property (nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden; -@property (nonatomic,getter=isToolbarHidden) BOOL toolbarHidden; // toolbar support is not really implemented yet - +@property (nonatomic, readonly, strong) UIViewController *topViewController; +@property (nonatomic, getter=isNavigationBarHidden) BOOL navigationBarHidden; +@property (nonatomic, getter=isToolbarHidden) BOOL toolbarHidden; // toolbar support is not really implemented yet @end diff --git a/UIKit/Classes/UINavigationController.m b/UIKit/Classes/UINavigationController.m index 0f333e79..fcd7a23c 100644 --- a/UIKit/Classes/UINavigationController.m +++ b/UIKit/Classes/UINavigationController.m @@ -28,36 +28,31 @@ */ #import "UINavigationController.h" -#import "UIViewController+UIPrivate.h" #import "UITabBarController.h" #import "UINavigationBar.h" #import "UIToolbar.h" -static const NSTimeInterval kAnimationDuration = 0.33; -static const CGFloat NavBarHeight = 28; -static const CGFloat ToolbarHeight = 28; +@interface UIViewController (UIPrivate) +- (void)_removeFromParentViewController; +@end -@implementation UINavigationController -@synthesize viewControllers=_viewControllers, delegate=_delegate, navigationBar=_navigationBar; -@synthesize toolbar=_toolbar, toolbarHidden=_toolbarHidden, navigationBarHidden=_navigationBarHidden; -@synthesize visibleViewController=_visibleViewController; +@implementation UINavigationController { + UIViewController *_visibleViewController; + BOOL _needsDeferredUpdate; + BOOL _isUpdating; + BOOL _toolbarHidden; +} -- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle +- (id)initWithRootViewController:(UIViewController *)rootViewController { - if ((self=[super initWithNibName:nibName bundle:bundle])) { - _viewControllers = [[NSMutableArray alloc] initWithCapacity:1]; - _navigationBar = [[UINavigationBar alloc] init]; + if ((self=[super initWithNibName:nil bundle:nil])) { + _navigationBar = [UINavigationBar new]; _navigationBar.delegate = self; - _toolbar = [[UIToolbar alloc] init]; + + _toolbar = [UIToolbar new]; _toolbarHidden = YES; - } - return self; -} -- (id)initWithRootViewController:(UIViewController *)rootViewController -{ - if ((self=[self initWithNibName:nil bundle:nil])) { - self.viewControllers = [NSArray arrayWithObject:rootViewController]; + self.viewControllers = @[rootViewController]; } return self; } @@ -65,178 +60,186 @@ - (id)initWithRootViewController:(UIViewController *)rootViewController - (void)dealloc { _navigationBar.delegate = nil; - [_viewControllers release]; - [_visibleViewController release]; - [_navigationBar release]; - [_toolbar release]; - [super dealloc]; } -- (void)setDelegate:(id)newDelegate +- (void)loadView { - _delegate = newDelegate; - _delegateHas.didShowViewController = [_delegate respondsToSelector:@selector(navigationController:didShowViewController:animated:)]; - _delegateHas.willShowViewController = [_delegate respondsToSelector:@selector(navigationController:willShowViewController:animated:)]; + self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)]; + self.view.clipsToBounds = YES; + + CGRect navbarRect; + CGRect contentRect; + CGRect toolbarRect; + [self _getNavbarRect:&navbarRect contentRect:&contentRect toolbarRect:&toolbarRect forBounds:self.view.bounds]; + + _toolbar.frame = toolbarRect; + _navigationBar.frame = navbarRect; + _visibleViewController.view.frame = contentRect; + + _toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; + _navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin; + _visibleViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + [self.view addSubview:_visibleViewController.view]; + [self.view addSubview:_navigationBar]; + [self.view addSubview:_toolbar]; } -- (CGRect)_navigationBarFrame +- (BOOL)shouldAutomaticallyForwardAppearanceMethods { - CGRect navBarFrame = self.view.bounds; - navBarFrame.size.height = NavBarHeight; - return navBarFrame; + return NO; } -- (CGRect)_toolbarFrame +- (void)_setNeedsDeferredUpdate { - CGRect toolbarRect = self.view.bounds; - toolbarRect.origin.y = toolbarRect.origin.y + toolbarRect.size.height - ToolbarHeight; - toolbarRect.size.height = ToolbarHeight; - return toolbarRect; + _needsDeferredUpdate = YES; + [self.view setNeedsLayout]; } -- (CGRect)_controllerFrameForTransition:(_UINavigationControllerVisibleControllerTransition)transition +- (void)_getNavbarRect:(CGRect *)navbarRect contentRect:(CGRect *)contentRect toolbarRect:(CGRect *)toolbarRect forBounds:(CGRect)bounds { - CGRect controllerFrame = self.view.bounds; + const CGRect navbar = CGRectMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds), CGRectGetWidth(bounds), _navigationBar.frame.size.height); + const CGRect toolbar = CGRectMake(CGRectGetMinX(bounds), CGRectGetMaxY(bounds)-_toolbar.frame.size.height, CGRectGetWidth(bounds), _toolbar.frame.size.height); + CGRect content = bounds; - // adjust for the nav bar if (!self.navigationBarHidden) { - controllerFrame.origin.y += NavBarHeight; - controllerFrame.size.height -= NavBarHeight; + content.origin.y += CGRectGetHeight(navbar); + content.size.height -= CGRectGetHeight(navbar); } - - // adjust for toolbar (if there is one) + if (!self.toolbarHidden) { - controllerFrame.size.height -= ToolbarHeight; - } - - if (transition == _UINavigationControllerVisibleControllerTransitionPushAnimated) { - controllerFrame = CGRectOffset(controllerFrame, controllerFrame.size.width, 0); - } else if (transition == _UINavigationControllerVisibleControllerTransitionPopAnimated) { - controllerFrame = CGRectOffset(controllerFrame, -controllerFrame.size.width, 0); + content.size.height -= CGRectGetHeight(toolbar); } - return controllerFrame; + if (navbarRect) *navbarRect = navbar; + if (toolbarRect) *toolbarRect = toolbar; + if (contentRect) *contentRect = content; } -- (void)_setVisibleViewControllerNeedsUpdate +- (void)_updateVisibleViewController:(BOOL)animated { - // schedules a deferred method to run - if (!_visibleViewControllerNeedsUpdate) { - _visibleViewControllerNeedsUpdate = YES; - [self performSelector:@selector(_updateVisibleViewController) withObject:nil afterDelay:0]; - } -} - -- (void)_updateVisibleViewController -{ - // do some bookkeeping - _visibleViewControllerNeedsUpdate = NO; - UIViewController *topViewController = [self.topViewController retain]; + _isUpdating = YES; - // make sure the new top view is both loaded and set to appear in the correct place - topViewController.view.frame = [self _controllerFrameForTransition:_visibleViewControllerTransition]; + UIViewController *newVisibleViewController = self.topViewController; + UIViewController *oldVisibleViewController = _visibleViewController; - if (_visibleViewControllerTransition == _UINavigationControllerVisibleControllerTransitionNone) { - [_visibleViewController viewWillDisappear:NO]; - [topViewController viewWillAppear:NO]; - - if (_delegateHas.willShowViewController) { - [_delegate navigationController:self willShowViewController:topViewController animated:NO]; - } + const BOOL isPushing = (oldVisibleViewController.parentViewController != nil); + const BOOL wasToolbarHidden = self.toolbarHidden; + const BOOL wasNavbarHidden = self.navigationBarHidden; - [_visibleViewController.view removeFromSuperview]; - [self.view insertSubview:topViewController.view atIndex:0]; - - [_visibleViewController viewDidDisappear:NO]; - [topViewController viewDidAppear:NO]; + [oldVisibleViewController beginAppearanceTransition:NO animated:animated]; + [newVisibleViewController beginAppearanceTransition:YES animated:animated]; + + [self.delegate navigationController:self willShowViewController:newVisibleViewController animated:animated]; - if (_delegateHas.didShowViewController) { - [_delegate navigationController:self didShowViewController:topViewController animated:NO]; - } - } else { - const CGRect visibleControllerFrame = (_visibleViewControllerTransition == _UINavigationControllerVisibleControllerTransitionPushAnimated) - ? [self _controllerFrameForTransition:_UINavigationControllerVisibleControllerTransitionPopAnimated] - : [self _controllerFrameForTransition:_UINavigationControllerVisibleControllerTransitionPushAnimated]; + _visibleViewController = newVisibleViewController; - const CGRect topControllerFrame = [self _controllerFrameForTransition:_UINavigationControllerVisibleControllerTransitionNone]; - - UIViewController *previouslyVisibleViewController = _visibleViewController; - - [UIView animateWithDuration:kAnimationDuration - animations:^(void) { - previouslyVisibleViewController.view.frame = visibleControllerFrame; - topViewController.view.frame = topControllerFrame; - } - completion:^(BOOL finished) { - [previouslyVisibleViewController.view removeFromSuperview]; - [previouslyVisibleViewController viewDidDisappear:YES]; - [topViewController viewDidAppear:YES]; - - if (_delegateHas.didShowViewController) { - [_delegate navigationController:self didShowViewController:topViewController animated:YES]; - } - }]; - } - - [_visibleViewController release]; - _visibleViewController = [topViewController retain]; + const CGRect bounds = self.view.bounds; + + CGRect navbarRect; + CGRect contentRect; + CGRect toolbarRect; + [self _getNavbarRect:&navbarRect contentRect:&contentRect toolbarRect:&toolbarRect forBounds:bounds]; - [topViewController release]; -} + _toolbar.transform = CGAffineTransformIdentity; + _toolbar.frame = toolbarRect; -- (void)loadView -{ - self.view = [[[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)] autorelease]; - self.view.clipsToBounds = YES; + _navigationBar.transform = CGAffineTransformIdentity; + _navigationBar.frame = navbarRect; + + newVisibleViewController.view.transform = CGAffineTransformIdentity; + newVisibleViewController.view.frame = contentRect; - UIViewController *viewController = self.visibleViewController; - viewController.view.frame = [self _controllerFrameForTransition:_UINavigationControllerVisibleControllerTransitionNone]; - viewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self.view addSubview:viewController.view]; + const CGAffineTransform inStartTransform = isPushing? CGAffineTransformMakeTranslation(bounds.size.width, 0) : CGAffineTransformMakeTranslation(-bounds.size.width, 0); + const CGAffineTransform outEndTransform = isPushing? CGAffineTransformMakeTranslation(-bounds.size.width, 0) : CGAffineTransformMakeTranslation(bounds.size.width, 0); + + CGAffineTransform toolbarEndTransform = CGAffineTransformIdentity; + CGAffineTransform navbarEndTransform = CGAffineTransformIdentity; - _navigationBar.frame = [self _navigationBarFrame]; - _navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth; - _navigationBar.hidden = self.navigationBarHidden; - [self.view addSubview:_navigationBar]; + if (wasToolbarHidden && !_toolbarHidden) { + _toolbar.transform = inStartTransform; + _toolbar.hidden = NO; + _toolbar.items = newVisibleViewController.toolbarItems; + } else if (!wasToolbarHidden && _toolbarHidden) { + toolbarEndTransform = outEndTransform; + _toolbar.transform = CGAffineTransformIdentity; + _toolbar.hidden = NO; + } else { + [_toolbar setItems:newVisibleViewController.toolbarItems animated:animated]; + } - _toolbar.frame = [self _toolbarFrame]; - _toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; - _toolbar.hidden = self.toolbarHidden; - [self.view addSubview:_toolbar]; -} + if (wasNavbarHidden && !_navigationBarHidden) { + _navigationBar.transform = inStartTransform; + _navigationBar.hidden = NO; + } else if (!wasNavbarHidden && _navigationBarHidden) { + navbarEndTransform = outEndTransform; + _navigationBar.transform = CGAffineTransformIdentity; + _navigationBar.hidden = NO; + } -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - [self.visibleViewController viewWillAppear:animated]; -} + newVisibleViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self.view insertSubview:newVisibleViewController.view atIndex:0]; + newVisibleViewController.view.transform = inStartTransform; + + [UIView animateWithDuration:animated? 0.33 : 0 + animations:^{ + oldVisibleViewController.view.transform = outEndTransform; + newVisibleViewController.view.transform = CGAffineTransformIdentity; + _toolbar.transform = toolbarEndTransform; + _navigationBar.transform = navbarEndTransform; + } + completion:^(BOOL finished) { + [oldVisibleViewController.view removeFromSuperview]; + + _toolbar.hidden = _toolbarHidden; + _navigationBar.hidden = _navigationBarHidden; + + [oldVisibleViewController endAppearanceTransition]; + [newVisibleViewController endAppearanceTransition]; + + // not sure if this is safe or not, really, but the real one must do something along these lines? + // it could perform this check in a variety of ways, though, with subtly different results so I'm + // not sure what's best. this seemed generally safest. + if (oldVisibleViewController && isPushing) { + [oldVisibleViewController didMoveToParentViewController:nil]; + } else { + [newVisibleViewController didMoveToParentViewController:self]; + } + + [self.delegate navigationController:self didShowViewController:newVisibleViewController animated:animated]; + }]; -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - [self.visibleViewController viewDidAppear:animated]; + _isUpdating = NO; } -- (void)viewWillDisappear:(BOOL)animated +- (void)viewWillLayoutSubviews { - [super viewWillDisappear:animated]; - [self.visibleViewController viewWillDisappear:animated]; + if (_needsDeferredUpdate) { + _needsDeferredUpdate = NO; + [self _updateVisibleViewController:NO]; + } } -- (void)viewDidDisappear:(BOOL)animated +- (NSArray *)viewControllers { - [super viewDidDisappear:animated]; - [self.visibleViewController viewDidDisappear:animated]; + return [self.childViewControllers copy]; } - (void)setViewControllers:(NSArray *)newViewControllers animated:(BOOL)animated { assert([newViewControllers count] >= 1); - if (![newViewControllers isEqualToArray:_viewControllers]) { - // remove them all in bulk - [_viewControllers makeObjectsPerformSelector:@selector(_setParentViewController:) withObject:nil]; - [_viewControllers removeAllObjects]; + if (![newViewControllers isEqualToArray:self.viewControllers]) { + // find the controllers we used to have that we won't be using anymore + NSMutableArray *removeViewControllers = [self.viewControllers mutableCopy]; + [removeViewControllers removeObjectsInArray:newViewControllers]; + + // these view controllers are not in the new collection, so we must remove them as children + // I'm pretty sure the real UIKit doesn't attempt to be so clever.. + for (UIViewController *controller in removeViewControllers) { + [controller willMoveToParentViewController:nil]; + [controller removeFromParentViewController]; + } // reset the nav bar _navigationBar.items = nil; @@ -255,59 +258,60 @@ - (void)setViewControllers:(NSArray *)newViewControllers - (UIViewController *)topViewController { - return [_viewControllers lastObject]; + return [self.childViewControllers lastObject]; } - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { assert(![viewController isKindOfClass:[UITabBarController class]]); - assert(![_viewControllers containsObject:viewController]); - - // override the animated property based on current state - animated = animated && _visibleViewController && self.view.window; - - // push on to controllers stack - [_viewControllers addObject:viewController]; - [_navigationBar pushNavigationItem:viewController.navigationItem animated:animated]; - - // take ownership responsibility - [viewController _setParentViewController:self]; - - // if animated and on screen, begin part of the transition immediately, specifically, get the new view - // on screen asap and tell the new controller it's about to be made visible in an animated fashion - if (animated) { - _visibleViewControllerTransition = _UINavigationControllerVisibleControllerTransitionPushAnimated; + assert(![self.viewControllers containsObject:viewController]); + assert(viewController.parentViewController == nil || viewController.parentViewController == self); - viewController.view.frame = [self _controllerFrameForTransition:_visibleViewControllerTransition]; + // this logic matches with the cleverness in setViewControllers which the real UIKit probably doens't do + // and probably isn't necessary :) + if (viewController.parentViewController != self) { - [_visibleViewController viewWillDisappear:YES]; - [viewController viewWillAppear:YES]; - - if (_delegateHas.willShowViewController) { - [_delegate navigationController:self willShowViewController:viewController animated:YES]; - } - - [self.view insertSubview:viewController.view atIndex:0]; - } + // note that -addChildViewController will call -willMoveToParentViewController: and that + // there's no matching call to -didMoveToParentViewController: here which is usually + // required. In my tests, it seems like the real UIKit hardly ever correctly calls the + // -didMoveToParentViewController: method on it's navigation controller children which + // makes me slightly crazy inside. I blame legacy (since child containment wasn't added + // until iOS 5), but it's still stupid. + [self addChildViewController:viewController]; + } - [self _setVisibleViewControllerNeedsUpdate]; + if (animated) { + [self _updateVisibleViewController:animated]; + } else { + [self _setNeedsDeferredUpdate]; + } + + [_navigationBar pushNavigationItem:viewController.navigationItem animated:animated]; } - (UIViewController *)popViewControllerAnimated:(BOOL)animated { // don't allow popping the rootViewController - if ([_viewControllers count] <= 1) { + if ([self.viewControllers count] <= 1) { return nil; } - - UIViewController *formerTopViewController = [self.topViewController retain]; - - // adjust the animate property - animated = animated && self.view.window; - // pop the controller stack - [_viewControllers removeLastObject]; + UIViewController *formerTopViewController = self.topViewController; + // the real thing seems to only bother calling -willMoveToParentViewController: + // here if the popped controller is the currently visible one. I have no idea why. + // if you pop several in a row, the ones buried in the stack don't seem to get called. + // it is possible that the real implementation is fancier and tracks if a child has + // been fully ever added or not before making this determination, but I haven't + // tried to test for that case yet since this was an easy thing to do to replicate + // the real world behavior I was seeing at the time of this writing. + if (formerTopViewController == _visibleViewController) { + [formerTopViewController willMoveToParentViewController:nil]; + } + + // the real thing seems to cheat here and removes the parent immediately even if animated + [formerTopViewController _removeFromParentViewController]; + // pop the nav bar - note that it's setting the delegate to nil and back because we use the nav bar's // -navigationBar:shouldPopItem: delegate method to determine when the user clicks the back button // but that method is also called when we do an animated pop like this, so this works around the cycle. @@ -316,49 +320,20 @@ - (UIViewController *)popViewControllerAnimated:(BOOL)animated [_navigationBar popNavigationItemAnimated:animated]; _navigationBar.delegate = self; - // give up ownership of the view controller - [formerTopViewController _setParentViewController:nil]; - - // if animated, begin part of the transition immediately, specifically, get the new top view on screen asap - // and tell the old visible controller it's about to be disappeared in an animated fashion - if (animated && self.view.window) { - // note the new top here so we don't have to use the accessor method all the time - UIViewController *topController = [self.topViewController retain]; - - _visibleViewControllerTransition = _UINavigationControllerVisibleControllerTransitionPopAnimated; - - // if we never updated the visible controller, we need to add the formerTopViewController - // on to the screen so we can see it disappear since we're attempting to animate this - if (!_visibleViewController) { - _visibleViewController = [formerTopViewController retain]; - _visibleViewController.view.frame = [self _controllerFrameForTransition:_UINavigationControllerVisibleControllerTransitionNone]; - [self.view insertSubview:_visibleViewController.view atIndex:0]; - } - - topController.view.frame = [self _controllerFrameForTransition:_visibleViewControllerTransition]; - - [_visibleViewController viewWillDisappear:YES]; - [topController viewWillAppear:YES]; - - if (_delegateHas.willShowViewController) { - [_delegate navigationController:self willShowViewController:topController animated:YES]; - } - - [self.view insertSubview:topController.view atIndex:0]; - - [topController release]; - } - - [self _setVisibleViewControllerNeedsUpdate]; + if (animated) { + [self _updateVisibleViewController:animated]; + } else { + [self _setNeedsDeferredUpdate]; + } - return [formerTopViewController autorelease]; + return formerTopViewController; } - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated { NSMutableArray *popped = [[NSMutableArray alloc] init]; - if ([_viewControllers containsObject:viewController]) { + if ([self.viewControllers containsObject:viewController]) { while (self.topViewController != viewController) { UIViewController *poppedController = [self popViewControllerAnimated:animated]; if (poppedController) { @@ -369,12 +344,12 @@ - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BO } } - return [popped autorelease]; + return popped; } - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated { - return [self popToViewController:[_viewControllers objectAtIndex:0] animated:animated]; + return [self popToViewController:[self.viewControllers objectAtIndex:0] animated:animated]; } - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item @@ -385,10 +360,34 @@ - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigati return NO; } -- (void)setToolbarHidden:(BOOL)hidden animated:(BOOL)animated +- (void)setToolbarHidden:(BOOL)hide animated:(BOOL)animated { - _toolbarHidden = hidden; - _toolbar.hidden = hidden; + if (hide != _toolbarHidden) { + _toolbarHidden = hide; + + if (animated && !_isUpdating) { + CGAffineTransform startTransform = hide? CGAffineTransformIdentity : CGAffineTransformMakeTranslation(0, _toolbar.frame.size.height); + CGAffineTransform endTransform = hide? CGAffineTransformMakeTranslation(0, _toolbar.frame.size.height) : CGAffineTransformIdentity; + + CGRect contentRect; + [self _getNavbarRect:NULL contentRect:&contentRect toolbarRect:NULL forBounds:self.view.bounds]; + + _toolbar.transform = startTransform; + _toolbar.hidden = NO; + + [UIView animateWithDuration:0.15 + animations:^{ + _visibleViewController.view.frame = contentRect; + _toolbar.transform = endTransform; + } + completion:^(BOOL finished) { + _toolbar.transform = CGAffineTransformIdentity; + _toolbar.hidden = _toolbarHidden; + }]; + } else { + _toolbar.hidden = _toolbarHidden; + } + } } - (void)setToolbarHidden:(BOOL)hidden @@ -411,13 +410,34 @@ - (CGSize)contentSizeForViewInPopover return self.topViewController.contentSizeForViewInPopover; } -- (void)setNavigationBarHidden:(BOOL)navigationBarHidden animated:(BOOL)animated; // doesn't yet animate +- (void)setNavigationBarHidden:(BOOL)hide animated:(BOOL)animated; { - _navigationBarHidden = navigationBarHidden; - - // this shouldn't just hide it, but should animate it out of view (if animated==YES) and then adjust the layout - // so the main view fills the whole space, etc. - _navigationBar.hidden = navigationBarHidden; + if (hide != _navigationBarHidden) { + _navigationBarHidden = hide; + + if (animated && !_isUpdating) { + CGAffineTransform startTransform = hide? CGAffineTransformIdentity : CGAffineTransformMakeTranslation(0, -_navigationBar.frame.size.height); + CGAffineTransform endTransform = hide? CGAffineTransformMakeTranslation(0, -_navigationBar.frame.size.height) : CGAffineTransformIdentity; + + CGRect contentRect; + [self _getNavbarRect:NULL contentRect:&contentRect toolbarRect:NULL forBounds:self.view.bounds]; + + _navigationBar.transform = startTransform; + _navigationBar.hidden = NO; + + [UIView animateWithDuration:0.15 + animations:^{ + _visibleViewController.view.frame = contentRect; + _navigationBar.transform = endTransform; + } + completion:^(BOOL finished) { + _navigationBar.transform = CGAffineTransformIdentity; + _navigationBar.hidden = _navigationBarHidden; + }]; + } else { + _navigationBar.hidden = _navigationBarHidden; + } + } } - (void)setNavigationBarHidden:(BOOL)navigationBarHidden @@ -425,4 +445,9 @@ - (void)setNavigationBarHidden:(BOOL)navigationBarHidden [self setNavigationBarHidden:navigationBarHidden animated:NO]; } +- (UIViewController *)defaultResponderChildViewController +{ + return self.topViewController; +} + @end diff --git a/UIKit/Classes/UINavigationItem+UIPrivate.h b/UIKit/Classes/UINavigationItem+UIPrivate.h index 43e80e94..884865a7 100644 --- a/UIKit/Classes/UINavigationItem+UIPrivate.h +++ b/UIKit/Classes/UINavigationItem+UIPrivate.h @@ -1,11 +1,5 @@ -// -// UINavigationItem+UIPrivate.h -// UIKit -// -// Created by Jim Dovey on 11-03-22. -// /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -35,9 +29,4 @@ #import "UINavigationItem.h" -@class UINavigationBar; - -@interface UINavigationItem (UIPrivate) -- (void)_setNavigationBar:(UINavigationBar *)navigationBar; -- (UINavigationBar *)_navigationBar; -@end +extern NSString *const UINavigationItemDidChange; diff --git a/UIKit/Classes/UINavigationItem.h b/UIKit/Classes/UINavigationItem.h index 60a91fef..bf797046 100644 --- a/UIKit/Classes/UINavigationItem.h +++ b/UIKit/Classes/UINavigationItem.h @@ -29,20 +29,9 @@ #import -@class UIBarButtonItem, UIView, UINavigationBar; - -@interface UINavigationItem : NSObject { -@private - NSString *_title; - NSString *_prompt; - UIBarButtonItem *_backBarButtonItem; - UIBarButtonItem *_leftBarButtonItem; - UIBarButtonItem *_rightBarButtonItem; - UIView *_titleView; - BOOL _hidesBackButton; - UINavigationBar *_navigationBar; -} +@class UIBarButtonItem, UIView; +@interface UINavigationItem : NSObject - (id)initWithTitle:(NSString *)title; - (void)setLeftBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated; - (void)setRightBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated; @@ -50,10 +39,9 @@ @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) NSString *prompt; -@property (nonatomic, retain) UIBarButtonItem *backBarButtonItem; -@property (nonatomic, retain) UIBarButtonItem *leftBarButtonItem; -@property (nonatomic, retain) UIBarButtonItem *rightBarButtonItem; -@property (nonatomic, retain) UIView *titleView; +@property (nonatomic, strong) UIBarButtonItem *backBarButtonItem; +@property (nonatomic, strong) UIBarButtonItem *leftBarButtonItem; +@property (nonatomic, strong) UIBarButtonItem *rightBarButtonItem; +@property (nonatomic, strong) UIView *titleView; @property (nonatomic, assign) BOOL hidesBackButton; - @end diff --git a/UIKit/Classes/UINavigationItem.m b/UIKit/Classes/UINavigationItem.m index 13157ea2..38ab3f15 100644 --- a/UIKit/Classes/UINavigationItem.m +++ b/UIKit/Classes/UINavigationItem.m @@ -27,95 +27,33 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UINavigationItem.h" -#import "UIBarButtonItem.h" #import "UINavigationItem+UIPrivate.h" -#import "UINavigationBar.h" -#import "UINavigationBar+UIPrivate.h" -static void * const UINavigationItemContext = "UINavigationItemContext"; +NSString *const UINavigationItemDidChange = @"UINavigationItemDidChange"; @implementation UINavigationItem -@synthesize title=_title, rightBarButtonItem=_rightBarButtonItem, titleView=_titleView, hidesBackButton=_hidesBackButton; -@synthesize leftBarButtonItem=_leftBarButtonItem, backBarButtonItem=_backBarButtonItem, prompt=_prompt; - -+ (NSSet *)_keyPathsTriggeringUIUpdates -{ - static NSSet * __keyPaths = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - __keyPaths = [[NSSet alloc] initWithObjects:@"title", @"prompt", @"backBarButtonItem", @"leftBarButtonItem", @"rightBarButtonItem", @"titleView", @"hidesBackButton", nil]; - }); - return __keyPaths; -} - (id)initWithTitle:(NSString *)theTitle { if ((self=[super init])) { - self.title = theTitle; + _title = [theTitle copy]; } return self; } -- (void)dealloc -{ - // removes automatic observation - [self _setNavigationBar:nil]; - - [_backBarButtonItem release]; - [_leftBarButtonItem release]; - [_rightBarButtonItem release]; - [_title release]; - [_titleView release]; - [_prompt release]; - [super dealloc]; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +- (void)setBackBarButtonItem:(UIBarButtonItem *)backBarButtonItem { - if (context != UINavigationItemContext) { - if ([[self superclass] instancesRespondToSelector:_cmd]) - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - return; + if (_backBarButtonItem != backBarButtonItem) { + _backBarButtonItem = backBarButtonItem; + [[NSNotificationCenter defaultCenter] postNotificationName:UINavigationItemDidChange object:self]; } - - [[self _navigationBar] _updateNavigationItem:self animated:NO]; -} - -- (void)_setNavigationBar:(UINavigationBar *)navigationBar -{ - // weak reference - if (_navigationBar == navigationBar) - return; - - if (_navigationBar != nil && navigationBar == nil) { - // remove observation - for (NSString * keyPath in [isa _keyPathsTriggeringUIUpdates]) { - [self removeObserver:self forKeyPath:keyPath]; - } - } - else if (navigationBar != nil) { - // observe property changes to notify UI element - for (NSString * keyPath in [isa _keyPathsTriggeringUIUpdates]) { - [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:UINavigationItemContext]; - } - } - - _navigationBar = navigationBar; -} - -- (UINavigationBar *)_navigationBar -{ - return _navigationBar; } - (void)setLeftBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { - if (item != _leftBarButtonItem) { - [self willChangeValueForKey: @"leftBarButtonItem"]; - [_leftBarButtonItem release]; - _leftBarButtonItem = [item retain]; - [self didChangeValueForKey: @"leftBarButtonItem"]; + if (_leftBarButtonItem != item) { + _leftBarButtonItem = item; + [[NSNotificationCenter defaultCenter] postNotificationName:UINavigationItemDidChange object:self]; } } @@ -126,11 +64,9 @@ - (void)setLeftBarButtonItem:(UIBarButtonItem *)item - (void)setRightBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { - if (item != _rightBarButtonItem) { - [self willChangeValueForKey: @"rightBarButtonItem"]; - [_rightBarButtonItem release]; - _rightBarButtonItem = [item retain]; - [self didChangeValueForKey: @"rightBarButtonItem"]; + if (_rightBarButtonItem != item) { + _rightBarButtonItem = item; + [[NSNotificationCenter defaultCenter] postNotificationName:UINavigationItemDidChange object:self]; } } @@ -141,9 +77,10 @@ - (void)setRightBarButtonItem:(UIBarButtonItem *)item - (void)setHidesBackButton:(BOOL)hidesBackButton animated:(BOOL)animated { - [self willChangeValueForKey: @"hidesBackButton"]; - _hidesBackButton = hidesBackButton; - [self didChangeValueForKey: @"hidesBackButton"]; + if (_hidesBackButton != hidesBackButton) { + _hidesBackButton = hidesBackButton; + [[NSNotificationCenter defaultCenter] postNotificationName:UINavigationItemDidChange object:self]; + } } - (void)setHidesBackButton:(BOOL)hidesBackButton @@ -151,12 +88,27 @@ - (void)setHidesBackButton:(BOOL)hidesBackButton [self setHidesBackButton:hidesBackButton animated:NO]; } -- (UIBarButtonItem *)backBarButtonItem +- (void)setTitle:(NSString *)title +{ + if (![_title isEqual:title]) { + _title = [title copy]; + [[NSNotificationCenter defaultCenter] postNotificationName:UINavigationItemDidChange object:self]; + } +} + +- (void)setPrompt:(NSString *)prompt +{ + if (![_prompt isEqual:prompt]) { + _prompt = [prompt copy]; + [[NSNotificationCenter defaultCenter] postNotificationName:UINavigationItemDidChange object:self]; + } +} + +- (void)setTitleView:(UIView *)titleView { - if (_backBarButtonItem) { - return _backBarButtonItem; - } else { - return [[[UIBarButtonItem alloc] initWithTitle:(self.title ?: @"Back") style:UIBarButtonItemStylePlain target:nil action:nil] autorelease]; + if (_titleView != titleView) { + _titleView = titleView; + [[NSNotificationCenter defaultCenter] postNotificationName:UINavigationItemDidChange object:self]; } } diff --git a/UIKit/Classes/UINinePartImage.h b/UIKit/Classes/UINinePartImage.h index 3f650105..d8dd9097 100644 --- a/UIKit/Classes/UINinePartImage.h +++ b/UIKit/Classes/UINinePartImage.h @@ -29,11 +29,7 @@ #import "UIImage+UIPrivate.h" -@interface UINinePartImage : UIImage { -@private - NSInteger _leftCapWidth; - NSInteger _topCapHeight; -} +@interface UINinePartImage : UIImage - (id)initWithRepresentations:(NSArray *)reps leftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight; diff --git a/UIKit/Classes/UINinePartImage.m b/UIKit/Classes/UINinePartImage.m index ada6e5ef..1170accf 100644 --- a/UIKit/Classes/UINinePartImage.m +++ b/UIKit/Classes/UINinePartImage.m @@ -30,7 +30,10 @@ #import "UINinePartImage.h" #import "UIImageRep.h" -@implementation UINinePartImage +@implementation UINinePartImage { + NSInteger _leftCapWidth; + NSInteger _topCapHeight; +} - (id)initWithRepresentations:(NSArray *)reps leftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight { diff --git a/UIKit/Classes/UIPageControl.h b/UIKit/Classes/UIPageControl.h index b47dc48b..b868e19a 100644 --- a/UIKit/Classes/UIPageControl.h +++ b/UIKit/Classes/UIPageControl.h @@ -30,12 +30,7 @@ #import "UIControl.h" -@interface UIPageControl : UIControl { - NSInteger _currentPage; - NSInteger _numberOfPages; -} - +@interface UIPageControl : UIControl @property (nonatomic) NSInteger currentPage; @property (nonatomic) NSInteger numberOfPages; - @end diff --git a/UIKit/Classes/UIPageControl.m b/UIKit/Classes/UIPageControl.m index d0b4eadf..e13ef0a1 100644 --- a/UIKit/Classes/UIPageControl.m +++ b/UIKit/Classes/UIPageControl.m @@ -30,7 +30,6 @@ #import "UIPageControl.h" @implementation UIPageControl -@synthesize currentPage=_currentPage, numberOfPages=_numberOfPages; - (void)setCurrentPage:(NSInteger)page { diff --git a/UIKit/Classes/UIPanGestureRecognizer.h b/UIKit/Classes/UIPanGestureRecognizer.h index 40a70dc8..92708d7c 100644 --- a/UIKit/Classes/UIPanGestureRecognizer.h +++ b/UIKit/Classes/UIPanGestureRecognizer.h @@ -38,19 +38,11 @@ // for UIScrollView but it certainly might make using the gesture recognizer in // a standalone setting somewhat more annoying. We'll have to see how it plays out. -@interface UIPanGestureRecognizer : UIGestureRecognizer { - NSUInteger _maximumNumberOfTouches; - NSUInteger _minimumNumberOfTouches; - CGPoint _translation; - CGPoint _velocity; - NSTimeInterval _lastMovementTime; -} - +@interface UIPanGestureRecognizer : UIGestureRecognizer - (CGPoint)translationInView:(UIView *)view; - (void)setTranslation:(CGPoint)translation inView:(UIView *)view; - (CGPoint)velocityInView:(UIView *)view; @property (nonatomic) NSUInteger maximumNumberOfTouches; @property (nonatomic) NSUInteger minimumNumberOfTouches; - @end diff --git a/UIKit/Classes/UIPanGestureRecognizer.m b/UIKit/Classes/UIPanGestureRecognizer.m index 98f2f20b..641f9014 100644 --- a/UIKit/Classes/UIPanGestureRecognizer.m +++ b/UIKit/Classes/UIPanGestureRecognizer.m @@ -29,22 +29,15 @@ #import "UIPanGestureRecognizer.h" #import "UIGestureRecognizerSubclass.h" -#import "UITouch+UIPrivate.h" -#import "UIEvent.h" +#import "UITouchEvent.h" +#import "UITouch.h" -static UITouch *PanTouch(NSSet *touches) -{ - for (UITouch *touch in touches) { - if ([touch _gesture] == _UITouchGesturePan) { - return touch; - } - } - return nil; +@implementation UIPanGestureRecognizer { + CGPoint _translation; + CGPoint _velocity; + NSTimeInterval _lastMovementTime; } -@implementation UIPanGestureRecognizer -@synthesize maximumNumberOfTouches=_maximumNumberOfTouches, minimumNumberOfTouches=_minimumNumberOfTouches; - - (id)initWithTarget:(id)target action:(SEL)action { if ((self=[super initWithTarget:target action:action])) { @@ -95,35 +88,42 @@ - (CGPoint)velocityInView:(UIView *)view return _velocity; } -- (void)_gesturesMoved:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - UITouch *touch = PanTouch([event touchesForGestureRecognizer:self]); + if (self.state == UIGestureRecognizerStatePossible) { + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + + if (touchEvent.touchEventGesture != UITouchEventGestureBegin) { + self.state = UIGestureRecognizerStateFailed; + } + } + } +} - // note that we being the gesture here in the _gesturesMoved:withEvent: method instead of the _gesturesBegan:withEvent: - // method because the pan gesture cannot be recognized until the user moves their fingers a bit and OSX won't tag the - // gesture as a pan until that movement has actually happened so we have to do the checking here. - if (self.state == UIGestureRecognizerStatePossible && touch) { - [self setTranslation:[touch _delta] inView:touch.view]; - _lastMovementTime = event.timestamp; - self.state = UIGestureRecognizerStateBegan; - } else if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) { - if (touch) { - if ([self _translate:[touch _delta] withEvent:event]) { +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + + if (touchEvent.touchEventGesture == UITouchEventGesturePan) { + if (self.state == UIGestureRecognizerStatePossible) { + _lastMovementTime = touchEvent.timestamp; + [self setTranslation:touchEvent.translation inView:touchEvent.touch.view]; + self.state = UIGestureRecognizerStateBegan; + } else if ([self _translate:touchEvent.translation withEvent:event]) { self.state = UIGestureRecognizerStateChanged; } - } else { - self.state = UIGestureRecognizerStateCancelled; } } } -- (void)_gesturesEnded:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) { - UITouch *touch = PanTouch([event touchesForGestureRecognizer:self]); - - if (touch) { - [self _translate:[touch _delta] withEvent:event]; + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + [self _translate:touchEvent.translation withEvent:touchEvent]; self.state = UIGestureRecognizerStateEnded; } else { self.state = UIGestureRecognizerStateCancelled; @@ -131,4 +131,11 @@ - (void)_gesturesEnded:(NSSet *)touches withEvent:(UIEvent *)event } } +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) { + self.state = UIGestureRecognizerStateCancelled; + } +} + @end diff --git a/UIKit/Classes/UIPasteboard.h b/UIKit/Classes/UIPasteboard.h index f7969329..5e10cdce 100644 --- a/UIKit/Classes/UIPasteboard.h +++ b/UIKit/Classes/UIPasteboard.h @@ -29,14 +29,15 @@ #import -@class UIImage, UIColor, NSPasteboard; - -@interface UIPasteboard : NSObject { - NSPasteboard *pasteboard; -} +@class UIImage, UIColor; +@interface UIPasteboard : NSObject + (UIPasteboard *)generalPasteboard; +- (void)addItems:(NSArray *)items; +- (void)setData:(NSData *)data forPasteboardType:(NSString *)pasteboardType; +- (void)setValue:(id)value forPasteboardType:(NSString *)pasteboardType; + @property (nonatomic,copy) NSURL *URL; @property (nonatomic,copy) NSArray *URLs; @property (nonatomic,copy) NSString *string; @@ -46,9 +47,4 @@ @property (nonatomic, copy) UIColor *color; @property (nonatomic, copy) NSArray *colors; @property (nonatomic, copy) NSArray *items; - -- (void)addItems:(NSArray *)items; -- (void)setData:(NSData *)data forPasteboardType:(NSString *)pasteboardType; -- (void)setValue:(id)value forPasteboardType:(NSString *)pasteboardType; - @end diff --git a/UIKit/Classes/UIPasteboard.m b/UIKit/Classes/UIPasteboard.m index f54d9627..8071c85e 100644 --- a/UIKit/Classes/UIPasteboard.m +++ b/UIKit/Classes/UIPasteboard.m @@ -64,14 +64,12 @@ static BOOL IsUIPasteboardPropertyListType(id object) // seemed to be the quickest way to get the job done at the time. Copying raw GIF NSData to the // pasteboard on iOS and tagging it as kUTTypeGIF seems to work just fine in the few places that // accept animated GIFs that I've tested so far on iOS so...... yeah. - if (UTTypeEqual((CFStringRef)type, kUTTypeGIF)) { + if (UTTypeEqual((__bridge CFStringRef)type, kUTTypeGIF)) { NSFileWrapper *fileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents:object]; [fileWrapper setPreferredFilename:@"image.gif"]; NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:fileWrapper]; NSAttributedString *str = [NSAttributedString attributedStringWithAttachment:attachment]; [pasteboardItem setData:[str RTFDFromRange:NSMakeRange(0, [str length]) documentAttributes:nil] forType:(NSString *)kUTTypeFlatRTFD]; - [attachment release]; - [fileWrapper release]; } [pasteboardItem setData:object forType:type]; } else if ([object isKindOfClass:[NSURL class]]) { @@ -81,25 +79,21 @@ static BOOL IsUIPasteboardPropertyListType(id object) } } - return [pasteboardItem autorelease]; + return pasteboardItem; } -@implementation UIPasteboard +@implementation UIPasteboard { + NSPasteboard *_pasteboard; +} - (id)initWithPasteboard:(NSPasteboard *)aPasteboard { if ((self=[super init])) { - pasteboard = [aPasteboard retain]; + _pasteboard = aPasteboard; } return self; } -- (void)dealloc -{ - [pasteboard release]; - [super dealloc]; -} - + (UIPasteboard *)generalPasteboard { static UIPasteboard *aPasteboard = nil; @@ -113,14 +107,14 @@ + (UIPasteboard *)generalPasteboard - (void)_writeObjects:(NSArray *)objects { - [pasteboard clearContents]; - [pasteboard writeObjects:objects]; + [_pasteboard clearContents]; + [_pasteboard writeObjects:objects]; } - (id)_objectsWithClasses:(NSArray *)types { NSDictionary *options = [NSDictionary dictionary]; - return [pasteboard readObjectsForClasses:types options:options]; + return [_pasteboard readObjectsForClasses:types options:options]; } - (void)setStrings:(NSArray *)strings @@ -180,7 +174,7 @@ - (NSArray *)images NSMutableArray *images = [NSMutableArray arrayWithCapacity:[rawImages count]]; for (NSImage *image in rawImages) { - [images addObject:[[[UIImage alloc] initWithNSImage:image] autorelease]]; + [images addObject:[[UIImage alloc] initWithNSImage:image]]; } return images; @@ -213,7 +207,7 @@ - (NSArray *)colors NSMutableArray *colors = [NSMutableArray arrayWithCapacity:[rawColors count]]; for (NSColor *color in rawColors) { - [colors addObject:[[[UIColor alloc] initWithNSColor:color] autorelease]]; + [colors addObject:[[UIColor alloc] initWithNSColor:color]]; } return colors; @@ -237,12 +231,12 @@ - (void)addItems:(NSArray *)items [objects addObject:PasteBoardItemWithDictionary(item)]; } - [pasteboard writeObjects:objects]; + [_pasteboard writeObjects:objects]; } - (void)setItems:(NSArray *)items { - [pasteboard clearContents]; + [_pasteboard clearContents]; [self addItems:items]; } @@ -251,13 +245,13 @@ - (NSArray *)items { NSMutableArray *items = [NSMutableArray arrayWithCapacity:0]; - for (NSPasteboardItem *item in [pasteboard pasteboardItems]) { + for (NSPasteboardItem *item in [_pasteboard pasteboardItems]) { NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:0]; for (NSString *type in [item types]) { id object = nil; - if (UTTypeConformsTo((CFStringRef)type, kUTTypeURL)) { + if (UTTypeConformsTo((__bridge CFStringRef)type, kUTTypeURL)) { object = [NSURL URLWithString:[item stringForType:type]]; } else { object = [item propertyListForType:type] ?: [item dataForType:type]; @@ -279,16 +273,16 @@ - (NSArray *)items - (void)setData:(NSData *)data forPasteboardType:(NSString *)pasteboardType { if (data && pasteboardType) { - [pasteboard clearContents]; - [pasteboard writeObjects:[NSArray arrayWithObject:PasteBoardItemWithDictionary([NSDictionary dictionaryWithObject:data forKey:pasteboardType])]]; + [_pasteboard clearContents]; + [_pasteboard writeObjects:[NSArray arrayWithObject:PasteBoardItemWithDictionary([NSDictionary dictionaryWithObject:data forKey:pasteboardType])]]; } } - (void)setValue:(id)value forPasteboardType:(NSString *)pasteboardType { if (pasteboardType && IsUIPasteboardPropertyListType(value)) { - [pasteboard clearContents]; - [pasteboard writeObjects:[NSArray arrayWithObject:PasteBoardItemWithDictionary([NSDictionary dictionaryWithObject:value forKey:pasteboardType])]]; + [_pasteboard clearContents]; + [_pasteboard writeObjects:[NSArray arrayWithObject:PasteBoardItemWithDictionary([NSDictionary dictionaryWithObject:value forKey:pasteboardType])]]; } } diff --git a/UIKit/Classes/UIPhotosAlbum.m b/UIKit/Classes/UIPhotosAlbum.m index 3a6ae18c..f42d0ed4 100644 --- a/UIKit/Classes/UIPhotosAlbum.m +++ b/UIKit/Classes/UIPhotosAlbum.m @@ -69,14 +69,9 @@ - (void)_writeImageWithInfo:(NSDictionary *)info if (target) { SEL action = NSSelectorFromString([info objectForKey:@"action"]); void *context = [[info objectForKey:@"context"] pointerValue]; - - NSMethodSignature *signature = [target methodSignatureForSelector:action]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:action]; - [invocation setArgument:&image atIndex:2]; - [invocation setArgument:&error atIndex:3]; - [invocation setArgument:&context atIndex:4]; - [invocation invokeWithTarget:target]; + typedef void(*ActionMethod)(id, SEL, id, NSError *, void *); + ActionMethod method = (ActionMethod)[target methodForSelector:action]; + method(target, action, image, error, context); } } diff --git a/UIKit/Classes/UIPickerView.h b/UIKit/Classes/UIPickerView.h index 35c78786..cf743f5f 100644 --- a/UIKit/Classes/UIPickerView.h +++ b/UIKit/Classes/UIPickerView.h @@ -37,17 +37,7 @@ @protocol UIPickerViewDataSource, UIPickerViewDelegate; -@interface UIPickerView : UIView { - __unsafe_unretained id _dataSource; - __unsafe_unretained id _delegate; - BOOL _showsSelectionIndicator; -} - -@property (nonatomic, assign) id dataSource; -@property (nonatomic, assign) id delegate; -@property (nonatomic, assign) BOOL showsSelectionIndicator; -@property (nonatomic, readonly) NSInteger numberOfComponents; - +@interface UIPickerView : UIView - (NSInteger) numberOfRowsInComponent: (NSInteger) component; // stub - (void) reloadAllComponents; // stub - (void) reloadComponent: (NSInteger) component; // stub @@ -56,6 +46,10 @@ - (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated; // stub - (UIView *) viewForRow: (NSInteger) row inComponent: (NSInteger) component; // stub +@property (nonatomic, assign) id dataSource; +@property (nonatomic, assign) id delegate; +@property (nonatomic, assign) BOOL showsSelectionIndicator; +@property (nonatomic, readonly) NSInteger numberOfComponents; @end diff --git a/UIKit/Classes/UIPickerView.m b/UIKit/Classes/UIPickerView.m index 294236e9..3c0ad853 100644 --- a/UIKit/Classes/UIPickerView.m +++ b/UIKit/Classes/UIPickerView.m @@ -37,10 +37,6 @@ @implementation UIPickerView -@synthesize showsSelectionIndicator = _showsSelectionIndicator; -@synthesize dataSource = _dataSource; -@synthesize delegate = _delegate; - - (id)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { @@ -52,7 +48,6 @@ - (void)dealloc { _dataSource = nil; _delegate = nil; - [super dealloc]; } - (NSInteger) numberOfComponents diff --git a/UIKit/Classes/UIPinchGestureRecognizer.h b/UIKit/Classes/UIPinchGestureRecognizer.h index 65ef6da6..0d90f91f 100644 --- a/UIKit/Classes/UIPinchGestureRecognizer.h +++ b/UIKit/Classes/UIPinchGestureRecognizer.h @@ -29,11 +29,7 @@ #import "UIGestureRecognizer.h" -@interface UIPinchGestureRecognizer : UIGestureRecognizer { - CGFloat _scale; -} - +@interface UIPinchGestureRecognizer : UIGestureRecognizer @property (nonatomic) CGFloat scale; @property (nonatomic, readonly) CGFloat velocity; - @end diff --git a/UIKit/Classes/UIPinchGestureRecognizer.m b/UIKit/Classes/UIPinchGestureRecognizer.m index d1d85db7..1c339b21 100644 --- a/UIKit/Classes/UIPinchGestureRecognizer.m +++ b/UIKit/Classes/UIPinchGestureRecognizer.m @@ -29,9 +29,9 @@ #import "UIPinchGestureRecognizer.h" #import "UIGestureRecognizerSubclass.h" +#import "UITouchEvent.h" @implementation UIPinchGestureRecognizer -@synthesize scale=_scale; - (id)initWithTarget:(id)target action:(SEL)action { @@ -46,4 +46,54 @@ - (CGFloat)velocity return 0; } +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (self.state == UIGestureRecognizerStatePossible) { + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + + if (touchEvent.touchEventGesture != UITouchEventGestureBegin) { + self.state = UIGestureRecognizerStateFailed; + } + } + } +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + + if (touchEvent.touchEventGesture == UITouchEventGesturePinch) { + if (self.state == UIGestureRecognizerStatePossible) { + _scale = touchEvent.magnification; + self.state = UIGestureRecognizerStateBegan; + } else { + _scale = touchEvent.magnification; + self.state = UIGestureRecognizerStateChanged; + } + } + } +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) { + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + _scale = touchEvent.magnification; + self.state = UIGestureRecognizerStateEnded; + } else { + self.state = UIGestureRecognizerStateCancelled; + } + } +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (self.state == UIGestureRecognizerStateBegan || self.state == UIGestureRecognizerStateChanged) { + self.state = UIGestureRecognizerStateCancelled; + } +} + @end diff --git a/UIKit/Classes/UIPopoverController.h b/UIKit/Classes/UIPopoverController.h index 9df164b9..22662c2a 100644 --- a/UIKit/Classes/UIPopoverController.h +++ b/UIKit/Classes/UIPopoverController.h @@ -29,7 +29,7 @@ #import -enum { +typedef NS_OPTIONS(NSUInteger, UIPopoverArrowDirection) { UIPopoverArrowDirectionUp = 1UL << 0, UIPopoverArrowDirectionDown = 1UL << 1, UIPopoverArrowDirectionLeft = 1UL << 2, @@ -38,7 +38,6 @@ enum { UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight, UIPopoverArrowDirectionUnknown = NSUIntegerMax }; -typedef NSUInteger UIPopoverArrowDirection; @class UIView, UIViewController, UIPopoverController, UIBarButtonItem, UIPopoverView; @@ -48,37 +47,20 @@ typedef NSUInteger UIPopoverArrowDirection; - (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController; @end -@interface UIPopoverController : NSObject { -@private - UIViewController *_contentViewController; - NSArray *_passthroughViews; - UIPopoverArrowDirection _popoverArrowDirection; - - UIPopoverView *_popoverView; - id _popoverWindow; - id _overlayWindow; - - BOOL _isDismissing; - - __unsafe_unretained id _delegate; - struct { - unsigned popoverControllerDidDismissPopover : 1; - unsigned popoverControllerShouldDismissPopover : 1; - } _delegateHas; -} - +@interface UIPopoverController : NSObject - (id)initWithContentViewController:(UIViewController *)viewController; - (void)setContentViewController:(UIViewController *)controller animated:(BOOL)animated; +- (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated; - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated; - (void)presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated; - (void)dismissPopoverAnimated:(BOOL)animated; @property (nonatomic, assign) id delegate; -@property (nonatomic, retain) UIViewController *contentViewController; +@property (nonatomic, strong) UIViewController *contentViewController; @property (nonatomic, readonly, getter=isPopoverVisible) BOOL popoverVisible; @property (nonatomic, copy) NSArray *passthroughViews; @property (nonatomic, readonly) UIPopoverArrowDirection popoverArrowDirection; - +@property (nonatomic) CGSize popoverContentSize; @end diff --git a/UIKit/Classes/UIPopoverController.m b/UIKit/Classes/UIPopoverController.m index c47ebfe2..c53ddde2 100644 --- a/UIKit/Classes/UIPopoverController.m +++ b/UIKit/Classes/UIPopoverController.m @@ -34,7 +34,7 @@ #import "UIScreenAppKitIntegration.h" #import "UIKitView.h" #import "UITouch.h" -#import "UIApplication+UIPrivate.h" +#import "UIApplicationAppKitIntegration.h" #import "UIPopoverView.h" #import "UIPopoverNSWindow.h" #import "UIPopoverOverlayNSView.h" @@ -119,13 +119,18 @@ static NSPoint PopoverWindowOrigin(NSWindow *inWindow, NSRect fromRect, NSSize p return windowRect.origin; } -@interface UIPopoverController () -- (void)_destroyPopover; -@end - -@implementation UIPopoverController -@synthesize delegate=_delegate, contentViewController=_contentViewController, passthroughViews=_passthroughViews; -@synthesize popoverArrowDirection=_popoverArrowDirection; +@implementation UIPopoverController { + UIPopoverView *_popoverView; + UIPopoverNSWindow *_popoverWindow; + NSWindow *_overlayWindow; + + BOOL _isDismissing; + + struct { + unsigned popoverControllerDidDismissPopover : 1; + unsigned popoverControllerShouldDismissPopover : 1; + } _delegateHas; +} - (id)init { @@ -147,9 +152,6 @@ - (id)initWithContentViewController:(UIViewController *)viewController - (void)dealloc { [self _destroyPopover]; - [_passthroughViews release]; - [_contentViewController release]; - [super dealloc]; } - (void)setDelegate:(id)newDelegate @@ -165,8 +167,7 @@ - (void)setContentViewController:(UIViewController *)controller animated:(BOOL)a if ([self isPopoverVisible]) { [_popoverView setContentView:controller.view animated:animated]; } - [_contentViewController release]; - _contentViewController = [controller retain]; + _contentViewController = controller; } } @@ -175,6 +176,16 @@ - (void)setContentViewController:(UIViewController *)viewController [self setContentViewController:viewController animated:NO]; } +- (void)setPopoverContentSize:(CGSize)size animated:(BOOL)animated +{ + _popoverContentSize = size; +} + +- (void)setPopoverContentSize:(CGSize)size +{ + [self setPopoverContentSize:size animated:NO]; +} + - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated { assert(_isDismissing == NO); @@ -182,9 +193,9 @@ - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrow assert(arrowDirections != UIPopoverArrowDirectionUnknown); assert(!CGRectIsNull(rect)); assert(!CGRectEqualToRect(rect,CGRectZero)); - assert([[view.window.screen UIKitView] window] != nil); + assert([view.window.screen.UIKitView window] != nil); - NSWindow *viewNSWindow = [[view.window.screen UIKitView] window]; + NSWindow *viewNSWindow = [view.window.screen.UIKitView window]; // only create new stuff if the popover isn't already visible if (![self isPopoverVisible]) { @@ -198,48 +209,39 @@ - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrow NSRect windowFrame = [viewNSWindow frame]; NSRect overlayContentRect = NSMakeRect(0,0,windowFrame.size.width,windowFrame.size.height); - UIPopoverOverlayNSView *popoverOverlayNSView = [[UIPopoverOverlayNSView alloc] initWithFrame:overlayContentRect popoverController:self]; - _overlayWindow = [[NSWindow alloc] initWithContentRect:overlayContentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; - [_overlayWindow setContentView:popoverOverlayNSView]; + [_overlayWindow setReleasedWhenClosed:NO]; + [_overlayWindow setContentView:[[UIPopoverOverlayNSView alloc] initWithFrame:overlayContentRect popoverController:self]]; [_overlayWindow setIgnoresMouseEvents:NO]; [_overlayWindow setOpaque:NO]; - [(NSWindow *)_overlayWindow setBackgroundColor:[NSColor clearColor]]; + [_overlayWindow setBackgroundColor:[NSColor clearColor]]; [_overlayWindow setFrameOrigin:windowFrame.origin]; [viewNSWindow addChildWindow:_overlayWindow ordered:NSWindowAbove]; // now build the actual popover view which represents the popover's chrome, and since it's a UIView, we need to build a UIKitView // as well to put it in our NSWindow... _popoverView = [[UIPopoverView alloc] initWithContentView:_contentViewController.view size:_contentViewController.contentSizeForViewInPopover]; + [_popoverView setHidden:YES]; - // this prevents a visible flash from sometimes occuring due to the fact that the window is created and added as a child before it has the - // proper origin set. this means it it ends up flashing at the bottom left corner of the screen sometimes before it - // gets down farther in this method where the actual origin is calculated and set. since the window is transparent, simply setting the UIView - // hidden gets around the problem since you then can't see any of the actual content that's in the window :) - _popoverView.hidden = YES; - - UIKitView *hostingView = [(UIKitView *)[UIKitView alloc] initWithFrame:NSRectFromCGRect([_popoverView bounds])]; - [[hostingView UIScreen] _setPopoverController:self]; + UIKitView *hostingView = [[UIKitView alloc] initWithFrame:NSRectFromCGRect([_popoverView bounds])]; [[hostingView UIWindow] addSubview:_popoverView]; // now finally make the actual popover window itself and attach it to the overlay window _popoverWindow = [[UIPopoverNSWindow alloc] initWithContentRect:[hostingView bounds] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]; - [(UIPopoverNSWindow *)_popoverWindow setContentView:hostingView]; - [(UIPopoverNSWindow *)_popoverWindow setPopoverController:self]; - [(UIPopoverNSWindow *)_popoverWindow setOpaque:NO]; - [(UIPopoverNSWindow *)_popoverWindow setBackgroundColor:[NSColor clearColor]]; + [_popoverWindow setReleasedWhenClosed:NO]; + [_popoverWindow setAlphaValue:0]; // prevents a flash as the window moves from the wrong position into the right position + [_popoverWindow setContentView:hostingView]; + [_popoverWindow setPopoverController:self]; + [_popoverWindow setOpaque:NO]; + [_popoverWindow setBackgroundColor:[NSColor clearColor]]; [_overlayWindow addChildWindow:_popoverWindow ordered:NSWindowAbove]; - [(UIPopoverNSWindow *)_popoverWindow makeFirstResponder:hostingView]; - - [hostingView release]; - [popoverOverlayNSView release]; } // cancel current touches (if any) to prevent the main window from losing track of events (such as if the user was holding down the mouse // button and a timer triggered the appearance of this popover. the window would possibly then not receive the mouseUp depending on how // all this works out... I first ran into this problem with NSMenus. A NSWindow is a bit different, but I think this makes sense here // too so premptively doing it to avoid potential problems.) - [[UIApplication sharedApplication] _cancelTouches]; + UIApplicationInterruptTouchesInView(nil); // now position the popover window according to the passed in parameters. CGRect windowRect = [view convertRect:rect toView:nil]; @@ -249,7 +251,9 @@ - (void)presentPopoverFromRect:(CGRect)rect inView:(UIView *)view permittedArrow // finally, let's show it! [_popoverWindow setFrameOrigin:PopoverWindowOrigin(_overlayWindow, NSRectFromCGRect(desktopScreenRect), NSSizeFromCGSize(_popoverView.frame.size), arrowDirections, &pointTo, &_popoverArrowDirection)]; - _popoverView.hidden = NO; + [_popoverWindow setAlphaValue:1]; + [_popoverView setHidden:NO]; + [_popoverWindow makeFirstResponder:[_popoverWindow contentView]]; [_popoverWindow makeKeyWindow]; // the window has to be visible before these coordinate conversions will work correctly (otherwise the UIScreen isn't attached to anything @@ -287,24 +291,21 @@ - (BOOL)isPopoverVisible - (void)_destroyPopover { - NSWindow *parentWindow = [[_overlayWindow parentWindow] retain]; + NSWindow *parentWindow = [_overlayWindow parentWindow]; [_overlayWindow removeChildWindow:_popoverWindow]; [parentWindow removeChildWindow:_overlayWindow]; - [_popoverView release]; - _popoverView = nil; - [_popoverWindow close]; - _popoverWindow = nil; - [_overlayWindow close]; + + _popoverWindow = nil; _overlayWindow = nil; + _popoverView = nil; _popoverArrowDirection = UIPopoverArrowDirectionUnknown; [parentWindow makeKeyAndOrderFront:self]; - [parentWindow release]; _isDismissing = NO; } diff --git a/UIKit/Classes/UIPopoverNSWindow.h b/UIKit/Classes/UIPopoverNSWindow.h index 31f737fb..54f88cec 100644 --- a/UIKit/Classes/UIPopoverNSWindow.h +++ b/UIKit/Classes/UIPopoverNSWindow.h @@ -31,9 +31,7 @@ @class UIPopoverController; -@interface UIPopoverNSWindow : NSWindow { - __unsafe_unretained UIPopoverController *_popoverController; -} +@interface UIPopoverNSWindow : NSWindow - (void)setPopoverController:(UIPopoverController *)controller; diff --git a/UIKit/Classes/UIPopoverNSWindow.m b/UIKit/Classes/UIPopoverNSWindow.m index 388ed271..522f1700 100644 --- a/UIKit/Classes/UIPopoverNSWindow.m +++ b/UIKit/Classes/UIPopoverNSWindow.m @@ -30,7 +30,9 @@ #import "UIPopoverNSWindow.h" #import "UIPopoverController+UIPrivate.h" -@implementation UIPopoverNSWindow +@implementation UIPopoverNSWindow { + __unsafe_unretained UIPopoverController *_popoverController; +} - (void)setPopoverController:(UIPopoverController *)controller { diff --git a/UIKit/Classes/UIPopoverOverlayNSView.h b/UIKit/Classes/UIPopoverOverlayNSView.h index 731e97a7..9119e61c 100644 --- a/UIKit/Classes/UIPopoverOverlayNSView.h +++ b/UIKit/Classes/UIPopoverOverlayNSView.h @@ -31,9 +31,7 @@ @class UIPopoverController; -@interface UIPopoverOverlayNSView : NSView { - UIPopoverController *_popoverController; -} +@interface UIPopoverOverlayNSView : NSView - (id)initWithFrame:(NSRect)frame popoverController:(UIPopoverController *)controller; diff --git a/UIKit/Classes/UIPopoverOverlayNSView.m b/UIKit/Classes/UIPopoverOverlayNSView.m index 58f425ff..528ae6ce 100644 --- a/UIKit/Classes/UIPopoverOverlayNSView.m +++ b/UIKit/Classes/UIPopoverOverlayNSView.m @@ -30,7 +30,9 @@ #import "UIPopoverOverlayNSView.h" #import "UIPopoverController+UIPrivate.h" -@implementation UIPopoverOverlayNSView +@implementation UIPopoverOverlayNSView { + __unsafe_unretained UIPopoverController *_popoverController; +} - (id)initWithFrame:(NSRect)frame popoverController:(UIPopoverController *)controller { diff --git a/UIKit/Classes/UIPopoverView.h b/UIKit/Classes/UIPopoverView.h index 6b7047ad..9ddf7cf0 100644 --- a/UIKit/Classes/UIPopoverView.h +++ b/UIKit/Classes/UIPopoverView.h @@ -31,12 +31,7 @@ @class UIImageView; -@interface UIPopoverView : UIView { - UIImageView *_backgroundView; - UIImageView *_arrowView; - UIView *_contentView; - UIView *_contentContainerView; -} +@interface UIPopoverView : UIView - (id)initWithContentView:(UIView *)aView size:(CGSize)aSize; @@ -44,7 +39,7 @@ - (void)setContentView:(UIView *)aView animated:(BOOL)animated; - (void)setContentSize:(CGSize)aSize animated:(BOOL)animated; -@property (nonatomic, retain) UIView *contentView; +@property (nonatomic, strong) UIView *contentView; @property (nonatomic, assign) CGSize contentSize; @end diff --git a/UIKit/Classes/UIPopoverView.m b/UIKit/Classes/UIPopoverView.m index c10444a7..5cf8581f 100644 --- a/UIKit/Classes/UIPopoverView.m +++ b/UIKit/Classes/UIPopoverView.m @@ -95,8 +95,11 @@ static CGFloat DistanceBetweenTwoPoints(CGPoint A, CGPoint B) return sqrtf((a*a) + (b*b)); } -@implementation UIPopoverView -@synthesize contentView=_contentView; +@implementation UIPopoverView { + UIImageView *_backgroundView; + UIImageView *_arrowView; + UIView *_contentContainerView; +} + (UIEdgeInsets)insetForArrows { @@ -129,7 +132,7 @@ + (CGSize)frameSizeForContentSize:(CGSize)contentSize withNavigationBar:(BOOL)ha - (id)initWithContentView:(UIView *)aView size:(CGSize)aSize { if ((self=[super initWithFrame:CGRectMake(0,0,320,480)])) { - _contentView = [aView retain]; + _contentView = aView; UIImage *backgroundImage = [UIImage _popoverBackgroundImage]; _backgroundView = [[UIImageView alloc] initWithImage:backgroundImage]; @@ -150,22 +153,14 @@ - (id)initWithContentView:(UIView *)aView size:(CGSize)aSize return self; } -- (void)dealloc -{ - [_backgroundView release]; - [_arrowView release]; - [_contentContainerView release]; - [_contentView release]; - [super dealloc]; -} - (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; } @@ -298,8 +293,7 @@ - (void)setContentView:(UIView *)aView animated:(BOOL)animated { if (aView != _contentView) { [_contentView removeFromSuperview]; - [_contentView release]; - _contentView = [aView retain]; + _contentView = aView; [self addSubview:_contentView]; } } @@ -312,7 +306,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/UIProgressView.h b/UIKit/Classes/UIProgressView.h index 15f359b4..fc6e98cd 100644 --- a/UIKit/Classes/UIProgressView.h +++ b/UIKit/Classes/UIProgressView.h @@ -28,20 +28,20 @@ */ #import "UIView.h" +#import "UIImage.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIProgressViewStyle) { UIProgressViewStyleDefault, UIProgressViewStyleBar, -} UIProgressViewStyle; - -@interface UIProgressView : UIView { - UIProgressViewStyle _progressViewStyle; - float _progress; -} +}; +@interface UIProgressView : UIView - (id)initWithProgressViewStyle:(UIProgressViewStyle)style; +- (void)setProgress:(float)progress animated:(BOOL)animated; @property (nonatomic) UIProgressViewStyle progressViewStyle; @property (nonatomic) float progress; +@property (nonatomic, strong) UIImage *progressImage; +@property (nonatomic, strong) UIImage *trackImage; @end diff --git a/UIKit/Classes/UIProgressView.m b/UIKit/Classes/UIProgressView.m index 514f8b74..7778ad58 100644 --- a/UIKit/Classes/UIProgressView.m +++ b/UIKit/Classes/UIProgressView.m @@ -30,7 +30,6 @@ #import "UIProgressView.h" @implementation UIProgressView -@synthesize progressViewStyle=_progressViewStyle, progress=_progress; - (id)initWithProgressViewStyle:(UIProgressViewStyle)style { @@ -48,10 +47,15 @@ - (void)setProgressViewStyle:(UIProgressViewStyle)style } } -- (void)setProgress:(float)p +- (void)setProgress:(float)progress { - if (p != _progress) { - _progress = MIN(1,MAX(0,p)); + [self setProgress:progress animated:NO]; +} + +- (void)setProgress:(float)progress animated:(BOOL)animated +{ + if (progress != _progress) { + _progress = MIN(1,MAX(0,progress)); [self setNeedsDisplay]; } } diff --git a/UIKit/Classes/UIResponder.h b/UIKit/Classes/UIResponder.h index b7904d9e..245cb76d 100644 --- a/UIKit/Classes/UIResponder.h +++ b/UIKit/Classes/UIResponder.h @@ -30,7 +30,6 @@ #import "UIEvent.h" @interface UIResponder : NSObject - - (UIResponder *)nextResponder; - (BOOL)isFirstResponder; - (BOOL)canBecomeFirstResponder; @@ -49,12 +48,33 @@ - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event; - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event; -@property (readonly, retain) UIView *inputAccessoryView; -@property (readonly, retain) UIView *inputView; -@property (readonly) NSUndoManager *undoManager; +@property (nonatomic, readonly) NSArray *keyCommands; +@property (readonly, strong) UIView *inputAccessoryView; +@property (readonly, strong) UIView *inputView; +@property (readonly) NSUndoManager *undoManager; @end +typedef NS_OPTIONS(NSInteger, UIKeyModifierFlags) { + UIKeyModifierAlphaShift = 1 << 16, // capslock + UIKeyModifierShift = 1 << 17, + UIKeyModifierControl = 1 << 18, + UIKeyModifierAlternate = 1 << 19, + UIKeyModifierCommand = 1 << 20, + UIKeyModifierNumericPad = 1 << 21, +}; + +extern NSString *const UIKeyInputUpArrow; +extern NSString *const UIKeyInputDownArrow; +extern NSString *const UIKeyInputLeftArrow; +extern NSString *const UIKeyInputRightArrow; +extern NSString *const UIKeyInputEscape; + +@interface UIKeyCommand : NSObject ++ (UIKeyCommand *)keyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)modifierFlags action:(SEL)action; +@property (nonatomic,readonly) NSString *input; +@property (nonatomic,readonly) UIKeyModifierFlags modifierFlags; +@end @interface NSObject (UIResponderStandardEditActions) - (void)copy:(id)sender; @@ -63,4 +83,13 @@ - (void)paste:(id)sender; - (void)select:(id)sender; - (void)selectAll:(id)sender; + +- (void)makeTextWritingDirectionLeftToRight:(id)sender; +- (void)makeTextWritingDirectionRightToLeft:(id)sender; +- (void)toggleBoldface:(id)sender; +- (void)toggleItalics:(id)sender; +- (void)toggleUnderline:(id)sender; + +- (void)increaseSize:(id)sender; +- (void)decreaseSize:(id)sender; @end diff --git a/UIKit/Classes/UIResponder.m b/UIKit/Classes/UIResponder.m index 55ece95e..88fed091 100644 --- a/UIKit/Classes/UIResponder.m +++ b/UIKit/Classes/UIResponder.m @@ -75,19 +75,24 @@ - (BOOL)becomeFirstResponder } if (didResign) { - [window makeKeyWindow]; // not sure about this :/ [window _setFirstResponder:self]; - // I have no idea how iOS manages this stuff, but here I'm modeling UIMenuController since it also uses the first - // responder to do its work. My thinking is that if there were an on-screen keyboard, something here could detect - // if self conforms to UITextInputTraits and UIKeyInput and/or UITextInput and then build/fetch the correct keyboard - // and assign that to the inputView property which would seperate the keyboard and inputs themselves from the stuff - // that actually displays them on screen. Of course on the Mac we don't need an on-screen keyboard, but there's - // possibly an argument to be made for supporting custom inputViews anyway. - UIInputController *controller = [UIInputController sharedInputController]; - controller.inputAccessoryView = self.inputAccessoryView; - controller.inputView = self.inputView; - [controller setInputVisible:YES animated:YES]; + if ([self conformsToProtocol:@protocol(UIKeyInput)]) { + // I have no idea how iOS manages this stuff, but here I'm modeling UIMenuController since it also uses the first + // responder to do its work. My thinking is that if there were an on-screen keyboard, something here could detect + // if self conforms to UITextInputTraits and UIKeyInput and/or UITextInput and then build/fetch the correct keyboard + // and assign that to the inputView property which would seperate the keyboard and inputs themselves from the stuff + // that actually displays them on screen. Of course on the Mac we don't need an on-screen keyboard, but there's + // possibly an argument to be made for supporting custom inputViews anyway. + UIInputController *controller = [UIInputController sharedInputController]; + controller.inputAccessoryView = self.inputAccessoryView; + controller.inputView = self.inputView; + controller.keyInputResponder = (UIResponder *)self; + [controller setInputVisible:YES animated:YES]; + + // key input won't very well work without this + [window makeKeyWindow]; + } return YES; } @@ -114,13 +119,39 @@ - (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]; } } +- (NSArray *)keyCommands +{ + return nil; +} + +- (UIView *)inputAccessoryView +{ + return nil; +} + +- (UIView *)inputView +{ + return nil; +} + +- (NSUndoManager *)undoManager +{ + return [[self nextResponder] undoManager]; +} + +// curiously, the documentation states that all of the following methods do nothing by default but that +// "immediate UIKit subclasses of UIResponder, particularly UIView, forward the message up the responder chain." +// oddly, though, if I use class_getInstanceMethod() to print the address of the actual C function being used +// by UIView, UIViewController, and UIResponder, they all point to the same function. So.... someone is wrong. +// I'm going to leave it like this for now because this is a lot simpler, IMO, and seems nicely logical. + - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [[self nextResponder] touchesBegan:touches withEvent:event]; @@ -141,23 +172,61 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event [[self nextResponder] touchesCancelled:touches withEvent:event]; } -- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {} -- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {} -- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {} +- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + [[self nextResponder] motionBegan:motion withEvent:event]; +} -- (UIView *)inputAccessoryView +- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { - return nil; + [[self nextResponder] motionEnded:motion withEvent:event]; } -- (UIView *)inputView +- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event +{ + [[self nextResponder] motionCancelled:motion withEvent:event]; +} + +@end + + +@implementation UIKeyCommand + ++ (UIKeyCommand *)keyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)modifierFlags action:(SEL)action { + // TODO return nil; } -- (NSUndoManager *)undoManager ++ (BOOL)supportsSecureCoding { - return [[self nextResponder] undoManager]; + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder +{ + // note, this requires NSSecureCoding, so you have to do something like this: + //id obj = [decoder decodeObjectOfClass:[MyClass class] forKey:@"myKey"]; + + // TODO + return [self init]; +} + +- (void)encodeWithCoder:(NSCoder *)encoder +{ + // TODO +} + +- (id)copyWithZone:(NSZone *)zone +{ + // this should be okay, because this is an immutable object + return self; } @end + +NSString *const UIKeyInputUpArrow = @"UIKeyInputUpArrow"; +NSString *const UIKeyInputDownArrow = @"UIKeyInputDownArrow"; +NSString *const UIKeyInputLeftArrow = @"UIKeyInputLeftArrow"; +NSString *const UIKeyInputRightArrow = @"UIKeyInputRightArrow"; +NSString *const UIKeyInputEscape = @"UIKeyInputEscape"; diff --git a/UIKit/Classes/UIResponderAppKitIntegration.h b/UIKit/Classes/UIResponderAppKitIntegration.h index 91a677fe..62f5f064 100644 --- a/UIKit/Classes/UIResponderAppKitIntegration.h +++ b/UIKit/Classes/UIResponderAppKitIntegration.h @@ -29,47 +29,38 @@ #import "UIResponder.h" -@class UIKey; +@class UIKey, UITouch; @interface UIResponder (AppKitIntegration) -// This message is sent up the responder chain so that views behind other views can make use of the scroll wheel (such as UIScrollView). +// Sent when the mouse scroll wheel changes. - (void)scrollWheelMoved:(CGPoint)delta withEvent:(UIEvent *)event; -// This is sent up the responder chain when the app gets a rightMouseDown-like event from OSX. There is no rightMouseDragged or rightMouseUp. +// Sent when the app gets a rightMouseDown-like event from OSX. There is no rightMouseDragged or rightMouseUp. - (void)rightClick:(UITouch *)touch withEvent:(UIEvent *)event; -// This message is sent up (down?) the responder chain. You may get these often - especially when the mouse moves over a view that has a lot -// of smaller subviews in it as the messages will be sent each time the view under the cursor changes. These only happen during normal mouse -// movement - not when clicking, click-dragging, etc so it won't happen in all possible cases that might maybe make sense. Also, due to the -// bolted-on nature of this, I'm not entirely convinced it is delivered from the best spot - but in practice, it'll probably be okay. -// NOTE: You might get this message twice since the message is sent both to the view being left and the one being exited and they could -// ultimately share the same superview or controller or something. -// If the mouse came in from outside the hosting UIKitView, the enteredView is nil. If the mouse left the UIKitView, the exitedView is nil. -- (void)mouseExitedView:(UIView *)exited enteredView:(UIView *)entered withEvent:(UIEvent *)event; - -// This passed along the responder chain like everything else. -- (void)mouseMoved:(CGPoint)delta withEvent:(UIEvent *)event; +// These message are sent often, but only during hover mouse movements - not when clicking, click-dragging, in a gesture, etc. +// NOTE: You might get these messages more than once if you are capturing it in superview as messages are generated based on the subview +// that is hit. -mouseMoved:withEvent: may send you a touch that is outside of your view in some cases (such as when the mouse is leaving +// your view's bounds), however that behavior is not always reliable depending on arrangement of views or if the view is near the edge of +// the UIKitView's bounds, etc. +- (void)mouseEntered:(UIView *)view withEvent:(UIEvent *)event; +- (void)mouseMoved:(UITouch *)touch withEvent:(UIEvent *)event; +- (void)mouseExited:(UIView *)view withEvent:(UIEvent *)event; // Return an NSCursor if you want to modify it or nil to use the default arrow. Follows responder chain. - (id)mouseCursorForEvent:(UIEvent *)event; // return an NSCursor if you want to modify it, return nil to use default -// This is a rough guess as to what might be coming in the future with UIKit. I suspect it'll be similar but perhaps more detailed. UIKey -// may or may not exist, etc. This will work for now in case it is needed. This is only triggered by keyDown: events and is not extensively -// implemented or tested at this point. This is sent to the firstResponder in the keyWindow. -// Note, that the UIEvent here will be an empty non-touch one and has no real purpose in the present implementation :) -- (void)keyPressed:(UIKey *)key withEvent:(UIEvent *)event; - @end @interface NSObject (UIResponderAppKitIntegrationKeyboardActions) // This is triggered from AppKit's cancelOperation: so it should be sent in largely the same circumstances. Generally you can think of it as mapping // to the ESC key, but CMD-. (period) also maps to it. -- (void)cancel:(id)sender; +- (void)cancelOperation:(id)sender; // This is mapped to CMD-Return and Enter and does not come from AppKit since it has no such convention as far as I've found. However it seemed like // a useful thing to define, really, so that's what I'm doing. :) -- (void)commit:(id)sender; +- (void)commitOperation:(id)sender; @end diff --git a/UIKit/Classes/UIResponderAppKitIntegration.m b/UIKit/Classes/UIResponderAppKitIntegration.m index 72fe6dce..01132a02 100644 --- a/UIKit/Classes/UIResponderAppKitIntegration.m +++ b/UIKit/Classes/UIResponderAppKitIntegration.m @@ -28,7 +28,6 @@ */ #import "UIResponderAppKitIntegration.h" -#import "UIEvent+UIPrivate.h" @implementation UIResponder (AppKitIntegration) @@ -42,29 +41,24 @@ - (void)rightClick:(UITouch *)touch withEvent:(UIEvent *)event [[self nextResponder] rightClick:touch withEvent:event]; } -- (void)mouseExitedView:(UIView *)exited enteredView:(UIView *)entered withEvent:(UIEvent *)event +- (void)mouseEntered:(UIView *)view withEvent:(UIEvent *)event { - [[self nextResponder] mouseExitedView:exited enteredView:entered withEvent:event]; + [[self nextResponder] mouseEntered:view withEvent:event]; } -- (void)mouseMoved:(CGPoint)delta withEvent:(UIEvent *)event +- (void)mouseMoved:(UITouch *)touch withEvent:(UIEvent *)event { - [[self nextResponder] mouseMoved:delta withEvent:event]; + [[self nextResponder] mouseMoved:touch withEvent:event]; } -- (id)mouseCursorForEvent:(UIEvent *)event +- (void)mouseExited:(UIView *)view withEvent:(UIEvent *)event { - return [[self nextResponder] mouseCursorForEvent:event]; + [[self nextResponder] mouseExited:view withEvent:event]; } -- (void)keyPressed:(UIKey *)key withEvent:(UIEvent *)event +- (id)mouseCursorForEvent:(UIEvent *)event { - UIResponder *responder = [self nextResponder]; - if (responder) { - [responder keyPressed:key withEvent:event]; - } else { - [event _setUnhandledKeyPressEvent]; - } + return [[self nextResponder] mouseCursorForEvent:event]; } @end diff --git a/UIKit/Classes/UIRotationGestureRecognizer.h b/UIKit/Classes/UIRotationGestureRecognizer.h index e53d31ed..ee81d3be 100644 --- a/UIKit/Classes/UIRotationGestureRecognizer.h +++ b/UIKit/Classes/UIRotationGestureRecognizer.h @@ -29,11 +29,7 @@ #import "UIGestureRecognizer.h" -@interface UIRotationGestureRecognizer : UIGestureRecognizer { - CGFloat _rotation; -} - +@interface UIRotationGestureRecognizer : UIGestureRecognizer @property (nonatomic) CGFloat rotation; @property (nonatomic,readonly) CGFloat velocity; - @end diff --git a/UIKit/Classes/UIRotationGestureRecognizer.m b/UIKit/Classes/UIRotationGestureRecognizer.m index e604ad4f..745957b9 100644 --- a/UIKit/Classes/UIRotationGestureRecognizer.m +++ b/UIKit/Classes/UIRotationGestureRecognizer.m @@ -31,7 +31,6 @@ #import "UIGestureRecognizerSubclass.h" @implementation UIRotationGestureRecognizer -@synthesize rotation=_rotation; - (id)initWithTarget:(id)target action:(SEL)action { diff --git a/UIKit/Classes/UIScreen+UIPrivate.h b/UIKit/Classes/UIScreen+UIPrivate.h index b6f98330..696ace6c 100644 --- a/UIKit/Classes/UIScreen+UIPrivate.h +++ b/UIKit/Classes/UIScreen+UIPrivate.h @@ -29,13 +29,13 @@ #import "UIScreen.h" -@class UIView, UIEvent; +@class UIKitView, CALayer; @interface UIScreen (UIPrivate) - (void)_setUIKitView:(UIKitView *)theView; +- (void)_setKeyWindow:(UIWindow *)window; +- (void)_addWindow:(UIWindow *)window; +- (void)_removeWindow:(UIWindow *)window; - (CALayer *)_layer; - (BOOL)_hasResizeIndicator; -- (void)_setPopoverController:(UIPopoverController *)controller; -- (UIPopoverController *)_popoverController; -- (UIView *)_hitTest:(CGPoint)clickPoint event:(UIEvent *)theEvent; @end diff --git a/UIKit/Classes/UIScreen.h b/UIKit/Classes/UIScreen.h index 78a8cd79..6a432150 100644 --- a/UIKit/Classes/UIScreen.h +++ b/UIKit/Classes/UIScreen.h @@ -34,24 +34,16 @@ extern NSString *const UIScreenDidConnectNotification; extern NSString *const UIScreenDidDisconnectNotification; extern NSString *const UIScreenModeDidChangeNotification; -@class UIImageView, CALayer, UIKitView, UIScreenMode, UIPopoverController; - -@interface UIScreen : NSObject { -@private - UIImageView *_grabber; - CALayer *_layer; - __unsafe_unretained UIKitView *_UIKitView; - UIScreenMode *_currentMode; - __unsafe_unretained UIPopoverController *_popoverController; -} +@class UIKitView, UIScreenMode, UIWindow; +@interface UIScreen : NSObject + (UIScreen *)mainScreen; + (NSArray *)screens; @property (nonatomic, readonly) CGRect bounds; @property (nonatomic, readonly) CGRect applicationFrame; @property (nonatomic, readonly, copy) NSArray *availableModes; // only ever returns the currentMode -@property (nonatomic, retain) UIScreenMode *currentMode; // ignores any attempt to set this +@property (nonatomic, strong) UIScreenMode *currentMode; // ignores any attempt to set this @property (nonatomic, readonly) CGFloat scale; - +@property (nonatomic) CGFloat brightness; // not implemented, of course @end diff --git a/UIKit/Classes/UIScreen.m b/UIKit/Classes/UIScreen.m index 0d1bae52..8bcd2187 100644 --- a/UIKit/Classes/UIScreen.m +++ b/UIKit/Classes/UIScreen.m @@ -28,18 +28,16 @@ */ #import "UIScreen.h" -#import "UIScreenAppKitIntegration.h" #import "UIImage+UIPrivate.h" #import "UIImageView.h" #import "UIApplication.h" -#import -#import #import "UIViewLayoutManager.h" -#import "UIColor.h" #import "UIScreenMode+UIPrivate.h" #import "UIWindow.h" #import "UIKitView.h" #import "UIView+UIPrivate.h" +#import +#import NSString *const UIScreenDidConnectNotification = @"UIScreenDidConnectNotification"; NSString *const UIScreenDidDisconnectNotification = @"UIScreenDidDisconnectNotification"; @@ -47,8 +45,13 @@ NSMutableArray *_allScreens = nil; -@implementation UIScreen -@synthesize currentMode=_currentMode; +@implementation UIScreen { + UIImageView *_grabber; + CALayer *_layer; + NSMutableArray *_windows; + __weak UIKitView *_UIKitView; + __weak UIWindow *_keyWindow; +} + (void)initialize { @@ -76,10 +79,13 @@ + (NSArray *)screens - (id)init { if ((self = [super init])) { - _layer = [[CALayer layer] retain]; + _layer = [CALayer layer]; _layer.delegate = self; // required to get the magic of the UIViewLayoutManager... _layer.layoutManager = [UIViewLayoutManager layoutManager]; + _windows = [[NSMutableArray alloc] init]; + _brightness = 1; + _grabber = [[UIImageView alloc] initWithImage:[UIImage _windowResizeGrabberImage]]; _grabber.layer.zPosition = 10000; [_layer addSublayer:_grabber.layer]; @@ -97,12 +103,6 @@ - (void)dealloc [_grabber.layer removeFromSuperlayer]; [_layer removeFromSuperlayer]; - - [_grabber release]; - [_layer release]; - [_currentMode release]; - - [super dealloc]; } - (CGFloat)scale @@ -114,16 +114,6 @@ - (CGFloat)scale } } -- (void)_setPopoverController:(UIPopoverController *)controller -{ - _popoverController = controller; -} - -- (UIPopoverController *)_popoverController -{ - return _popoverController; -} - - (BOOL)_hasResizeIndicator { NSWindow *realWindow = [_UIKitView window]; @@ -189,11 +179,7 @@ - (void)_UIKitViewFrameDidChange - (void)_NSScreenDidChange { - for (UIWindow *window in [[UIApplication sharedApplication].windows reverseObjectEnumerator]) { - if (window.screen == self) { - [window _didMoveToScreen]; - } - } + [self.windows makeObjectsPerformSelector:@selector(_didMoveToScreen)]; } - (void)_setUIKitView:(id)theView @@ -217,24 +203,44 @@ - (void)_setUIKitView:(id)theView } } +- (UIKitView *)UIKitView +{ + return _UIKitView; +} + - (NSArray *)availableModes { return (self.currentMode)? [NSArray arrayWithObject:self.currentMode] : nil; } -- (UIView *)_hitTest:(CGPoint)clickPoint event:(UIEvent *)theEvent +- (void)_addWindow:(UIWindow *)window { - for (UIWindow *window in [[UIApplication sharedApplication].windows reverseObjectEnumerator]) { - if (window.screen == self) { - CGPoint windowPoint = [window convertPoint:clickPoint fromWindow:nil]; - UIView *clickedView = [window hitTest:windowPoint withEvent:theEvent]; - if (clickedView) { - return clickedView; - } - } + [_windows addObject:[NSValue valueWithNonretainedObject:window]]; +} + +- (void)_removeWindow:(UIWindow *)window +{ + if (_keyWindow == window) { + _keyWindow = nil; } - - return nil; + + [_windows removeObject:[NSValue valueWithNonretainedObject:window]]; +} + +- (NSArray *)windows +{ + return [_windows valueForKey:@"nonretainedObjectValue"]; +} + +- (UIWindow *)keyWindow +{ + return _keyWindow; +} + +- (void)_setKeyWindow:(UIWindow *)window +{ + NSAssert([self.windows containsObject:window], @"cannot set key window to a window not on this screen"); + _keyWindow = window; } - (NSString *)description diff --git a/UIKit/Classes/UIScreenAppKitIntegration.h b/UIKit/Classes/UIScreenAppKitIntegration.h index a533af85..5e0358e4 100644 --- a/UIKit/Classes/UIScreenAppKitIntegration.h +++ b/UIKit/Classes/UIScreenAppKitIntegration.h @@ -28,10 +28,22 @@ */ #import "UIScreen.h" +#import "UIKitView.h" @interface UIScreen (AppKitIntegration) + +// the windows that make this screen their home +@property (nonatomic, readonly, copy) NSArray *windows; + +// the window from the -windows array which is this screen's key window. this is not really how iOS is likely to work +// as iOS seems to track a single key window for the whole app, but on OSX the user can change the key window out from +// under the app, so this entire thing has to be managed differently. my design here is that each screen has a potential +// key window which is what is set when a UIWindow is told to become key. the app's keyWindow (as reported by UIApplication) +// will be the keyWindow of the screen that's currently on the NSWindow that's key.... yeah... confusing, eh? +@property (nonatomic, readonly) UIWindow *keyWindow; + // the real NSView that the screen lives on (or nil if there isn't one) -- (UIKitView *)UIKitView; +@property (nonatomic, readonly) UIKitView *UIKitView; // promotes this screen to the main screen // this only changes what [UIScreen mainScreen] returns in the future, it doesn't move anything between views, etc. diff --git a/UIKit/Classes/UIScreenAppKitIntegration.m b/UIKit/Classes/UIScreenAppKitIntegration.m index 6fb63c4e..05443ad1 100644 --- a/UIKit/Classes/UIScreenAppKitIntegration.m +++ b/UIKit/Classes/UIScreenAppKitIntegration.m @@ -35,10 +35,7 @@ extern NSMutableArray *_allScreens; @implementation UIScreen (AppKitIntegration) -- (UIKitView *)UIKitView -{ - return _UIKitView; -} +@dynamic UIKitView, windows, keyWindow; - (CGPoint)convertPoint:(CGPoint)toConvert toScreen:(UIScreen *)toScreen { @@ -46,11 +43,11 @@ - (CGPoint)convertPoint:(CGPoint)toConvert toScreen:(UIScreen *)toScreen return toConvert; } else { // Go all the way through OSX screen coordinates. - NSPoint screenCoords = [[_UIKitView window] convertBaseToScreen:[_UIKitView convertPoint:NSPointFromCGPoint(toConvert) toView:nil]]; + NSPoint screenCoords = [[self.UIKitView window] convertBaseToScreen:[self.UIKitView convertPoint:NSPointFromCGPoint(toConvert) toView:nil]]; if (toScreen) { // Now from there back to the toScreen's window's base - return NSPointToCGPoint([[toScreen UIKitView] convertPoint:[[[toScreen UIKitView] window] convertScreenToBase:screenCoords] fromView:nil]); + return NSPointToCGPoint([toScreen.UIKitView convertPoint:[[toScreen.UIKitView window] convertScreenToBase:screenCoords] fromView:nil]); } else { return NSPointToCGPoint(screenCoords); } @@ -66,13 +63,13 @@ - (CGPoint)convertPoint:(CGPoint)toConvert fromScreen:(UIScreen *)fromScreen if (fromScreen) { // Go all the way through OSX screen coordinates. - screenCoords = [[[fromScreen UIKitView] window] convertBaseToScreen:[[fromScreen UIKitView] convertPoint:NSPointFromCGPoint(toConvert) toView:nil]]; + screenCoords = [[fromScreen.UIKitView window] convertBaseToScreen:[fromScreen.UIKitView convertPoint:NSPointFromCGPoint(toConvert) toView:nil]]; } else { screenCoords = NSPointFromCGPoint(toConvert); } // Now from there back to the our screen - return NSPointToCGPoint([_UIKitView convertPoint:[[_UIKitView window] convertScreenToBase:screenCoords] fromView:nil]); + return NSPointToCGPoint([self.UIKitView convertPoint:[[self.UIKitView window] convertScreenToBase:screenCoords] fromView:nil]); } } diff --git a/UIKit/Classes/UIScreenMode.h b/UIKit/Classes/UIScreenMode.h index 8f7c646a..ee134047 100644 --- a/UIKit/Classes/UIScreenMode.h +++ b/UIKit/Classes/UIScreenMode.h @@ -29,12 +29,7 @@ #import -@interface UIScreenMode : NSObject { - CGFloat _pixelAspectRatio; - CGSize _size; -} - +@interface UIScreenMode : NSObject @property (readonly,nonatomic) CGFloat pixelAspectRatio; @property (readonly,nonatomic) CGSize size; - @end diff --git a/UIKit/Classes/UIScreenMode.m b/UIKit/Classes/UIScreenMode.m index 2496f8a7..a8ac7eb6 100644 --- a/UIKit/Classes/UIScreenMode.m +++ b/UIKit/Classes/UIScreenMode.m @@ -32,7 +32,6 @@ #import @implementation UIScreenMode -@synthesize pixelAspectRatio=_pixelAspectRatio, size=_size; + (id)screenModeWithNSView:(NSView *)theNSView { @@ -40,7 +39,7 @@ + (id)screenModeWithNSView:(NSView *)theNSView UIScreenMode *mode = [[self alloc] init]; mode->_size = NSSizeToCGSize([theNSView bounds].size); mode->_pixelAspectRatio = 1; - return [mode autorelease]; + return mode; } else { return nil; } diff --git a/UIKit/Classes/UIScrollView.h b/UIKit/Classes/UIScrollView.h index 35e1d137..609b9084 100644 --- a/UIKit/Classes/UIScrollView.h +++ b/UIKit/Classes/UIScrollView.h @@ -29,16 +29,16 @@ #import "UIView.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIScrollViewIndicatorStyle) { UIScrollViewIndicatorStyleDefault, UIScrollViewIndicatorStyleBlack, UIScrollViewIndicatorStyleWhite -} UIScrollViewIndicatorStyle; +}; extern const float UIScrollViewDecelerationRateNormal; extern const float UIScrollViewDecelerationRateFast; -@class UIScroller, UIImageView, UIScrollView, UIPanGestureRecognizer, UIScrollWheelGestureRecognizer; +@class UIImageView, UIScrollView, UIPanGestureRecognizer, UIScrollWheelGestureRecognizer; @protocol UIScrollViewDelegate @optional @@ -52,64 +52,13 @@ extern const float UIScrollViewDecelerationRateFast; - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view; - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale; - (void)scrollViewDidZoom:(UIScrollView *)scrollView; +- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView; @end -@interface UIScrollView : UIView { -@package - __unsafe_unretained id _delegate; -@private - CGPoint _contentOffset; - CGSize _contentSize; - UIEdgeInsets _contentInset; - UIEdgeInsets _scrollIndicatorInsets; - UIScroller *_verticalScroller; - UIScroller *_horizontalScroller; - BOOL _showsVerticalScrollIndicator; - BOOL _showsHorizontalScrollIndicator; - float _maximumZoomScale; - float _minimumZoomScale; - BOOL _scrollsToTop; - UIScrollViewIndicatorStyle _indicatorStyle; - BOOL _delaysContentTouches; - BOOL _canCancelContentTouches; - BOOL _pagingEnabled; - float _decelerationRate; - - BOOL _bouncesZoom; - BOOL _bounces; - BOOL _zooming; - BOOL _dragging; - BOOL _decelerating; - - UIPanGestureRecognizer *_panGestureRecognizer; - UIScrollWheelGestureRecognizer *_scrollWheelGestureRecognizer; - - id _scrollAnimation; - NSTimer *_scrollTimer; - - struct { - unsigned scrollViewDidScroll : 1; - unsigned scrollViewWillBeginDragging : 1; - unsigned scrollViewDidEndDragging : 1; - unsigned viewForZoomingInScrollView : 1; - unsigned scrollViewWillBeginZooming : 1; - unsigned scrollViewDidEndZooming : 1; - unsigned scrollViewDidZoom : 1; - unsigned scrollViewDidEndScrollingAnimation : 1; - unsigned scrollViewWillBeginDecelerating : 1; - unsigned scrollViewDidEndDecelerating : 1; - } _delegateCan; - - // should be flag struct - BOOL _alwaysBounceHorizontal; - BOOL _alwaysBounceVertical; -} - +@interface UIScrollView : UIView - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated; - - (void)setZoomScale:(float)scale animated:(BOOL)animated; - (void)zoomToRect:(CGRect)rect animated:(BOOL)animated; - - (void)setContentOffset:(CGPoint)theOffset animated:(BOOL)animated; - (void)flashScrollIndicators; // does nothing @@ -128,21 +77,18 @@ extern const float UIScrollViewDecelerationRateFast; @property (nonatomic) BOOL scrollsToTop; // no effect @property (nonatomic) BOOL delaysContentTouches; // no effect @property (nonatomic) BOOL canCancelContentTouches; // no effect +@property (nonatomic, getter=isDirectionalLockEnabled) BOOL directionalLockEnabled; // no effect @property (nonatomic, readonly, getter=isDragging) BOOL dragging; @property (nonatomic, readonly, getter=isTracking) BOOL tracking; // always returns NO @property (nonatomic, readonly, getter=isDecelerating) BOOL decelerating; // always returns NO @property (nonatomic, assign) BOOL pagingEnabled; @property (nonatomic) float decelerationRate; - @property (nonatomic) float maximumZoomScale; @property (nonatomic) float minimumZoomScale; @property (nonatomic) float zoomScale; @property (nonatomic, readonly, getter=isZooming) BOOL zooming; @property (nonatomic, readonly, getter=isZoomBouncing) BOOL zoomBouncing; // always NO @property (nonatomic) BOOL bouncesZoom; // no effect - @property (nonatomic, readonly) UIPanGestureRecognizer *panGestureRecognizer; @property (nonatomic, readonly) UIScrollWheelGestureRecognizer *scrollWheelGestureRecognizer; // non-standard - - @end diff --git a/UIKit/Classes/UIScrollView.m b/UIKit/Classes/UIScrollView.m index 6db238a9..d4e3b2f1 100644 --- a/UIKit/Classes/UIScrollView.m +++ b/UIKit/Classes/UIScrollView.m @@ -28,13 +28,8 @@ */ #import "UIScrollView.h" -#import "UIView+UIPrivate.h" #import "UIScroller.h" -#import "UIScreen+UIPrivate.h" -#import "UIWindow.h" #import "UITouch.h" -#import "UIImageView.h" -#import "UIImage+UIPrivate.h" #import "UIResponderAppKitIntegration.h" #import "UIScrollViewAnimationScroll.h" #import "UIScrollViewAnimationDeceleration.h" @@ -52,14 +47,26 @@ @interface UIScrollView () <_UIScrollerDelegate> @end -@implementation UIScrollView -@synthesize contentOffset=_contentOffset, contentInset=_contentInset, scrollIndicatorInsets=_scrollIndicatorInsets; -@synthesize showsHorizontalScrollIndicator=_showsHorizontalScrollIndicator, showsVerticalScrollIndicator=_showsVerticalScrollIndicator, contentSize=_contentSize; -@synthesize maximumZoomScale=_maximumZoomScale, minimumZoomScale=_minimumZoomScale, scrollsToTop=_scrollsToTop; -@synthesize indicatorStyle=_indicatorStyle, delaysContentTouches=_delaysContentTouches, delegate=_delegate, pagingEnabled=_pagingEnabled; -@synthesize canCancelContentTouches=_canCancelContentTouches, bouncesZoom=_bouncesZoom, zooming=_zooming; -@synthesize alwaysBounceVertical=_alwaysBounceVertical, alwaysBounceHorizontal=_alwaysBounceHorizontal, bounces=_bounces; -@synthesize decelerationRate=_decelerationRate, scrollWheelGestureRecognizer=_scrollWheelGestureRecognizer, panGestureRecognizer=_panGestureRecognizer; +@implementation UIScrollView { + UIScroller *_verticalScroller; + UIScroller *_horizontalScroller; + + UIScrollViewAnimation *_scrollAnimation; + NSTimer *_scrollTimer; + + struct { + unsigned scrollViewDidScroll : 1; + unsigned scrollViewWillBeginDragging : 1; + unsigned scrollViewDidEndDragging : 1; + unsigned viewForZoomingInScrollView : 1; + unsigned scrollViewWillBeginZooming : 1; + unsigned scrollViewDidEndZooming : 1; + unsigned scrollViewDidZoom : 1; + unsigned scrollViewDidEndScrollingAnimation : 1; + unsigned scrollViewWillBeginDecelerating : 1; + unsigned scrollViewDidEndDecelerating : 1; + } _delegateCan; +} - (id)initWithFrame:(CGRect)frame { @@ -108,12 +115,6 @@ - (void)dealloc _horizontalScroller.delegate = nil; _verticalScroller.delegate = nil; - [_panGestureRecognizer release]; - [_scrollWheelGestureRecognizer release]; - [_scrollAnimation release]; - [_verticalScroller release]; - [_horizontalScroller release]; - [super dealloc]; } - (void)setDelegate:(id)newDelegate @@ -194,7 +195,6 @@ - (void)_cancelScrollAnimation [_scrollTimer invalidate]; _scrollTimer = nil; - [_scrollAnimation release]; _scrollAnimation = nil; if (_delegateCan.scrollViewDidEndScrollingAnimation) { @@ -222,7 +222,8 @@ - (void)_updateScrollAnimation - (void)_setScrollAnimation:(UIScrollViewAnimation *)animation { [self _cancelScrollAnimation]; - _scrollAnimation = [animation retain]; + + _scrollAnimation = animation; if (!_scrollTimer) { _scrollTimer = [NSTimer scheduledTimerWithTimeInterval:1/(NSTimeInterval)UIScrollViewScrollAnimationFramesPerSecond target:self selector:@selector(_updateScrollAnimation) userInfo:nil repeats:YES]; @@ -317,27 +318,38 @@ - (void)insertSubview:(UIView *)subview atIndex:(NSInteger)index [self _bringScrollersToFront]; } +- (void)_updateBounds +{ + CGRect bounds = self.bounds; + bounds.origin.x = _contentOffset.x - _contentInset.left; + bounds.origin.y = _contentOffset.y - _contentInset.top; + self.bounds = bounds; + + [self _updateScrollers]; + [self setNeedsLayout]; +} + - (void)setContentOffset:(CGPoint)theOffset animated:(BOOL)animated { if (animated) { - UIScrollViewAnimationScroll *animation = [[UIScrollViewAnimationScroll alloc] initWithScrollView:self - fromContentOffset:self.contentOffset - toContentOffset:theOffset - duration:UIScrollViewAnimationDuration - curve:UIScrollViewAnimationScrollCurveLinear]; - [self _setScrollAnimation:animation]; - [animation release]; + UIScrollViewAnimationScroll *animation = nil; + + if ([_scrollAnimation isKindOfClass:[UIScrollViewAnimationScroll class]]) { + animation = (UIScrollViewAnimationScroll *)_scrollAnimation; + } + + if (!animation || !CGPointEqualToPoint(theOffset, animation.endContentOffset)) { + [self _setScrollAnimation:[[UIScrollViewAnimationScroll alloc] initWithScrollView:self + fromContentOffset:self.contentOffset + toContentOffset:theOffset + duration:UIScrollViewAnimationDuration + curve:UIScrollViewAnimationScrollCurveLinear]]; + } } else { _contentOffset.x = roundf(theOffset.x); _contentOffset.y = roundf(theOffset.y); - CGRect bounds = self.bounds; - bounds.origin.x = _contentOffset.x+_contentInset.left; - bounds.origin.y = _contentOffset.y+_contentInset.top; - self.bounds = bounds; - - [self _updateScrollers]; - [self setNeedsLayout]; + [self _updateBounds]; if (_delegateCan.scrollViewDidScroll) { [_delegate scrollViewDidScroll:self]; @@ -350,6 +362,20 @@ - (void)setContentOffset:(CGPoint)theOffset [self setContentOffset:theOffset animated:NO]; } +- (void)setContentInset:(UIEdgeInsets)contentInset +{ + if (!UIEdgeInsetsEqualToEdgeInsets(contentInset, _contentInset)) { + const CGFloat x = contentInset.left - _contentInset.left; + const CGFloat y = contentInset.top - _contentInset.top; + + _contentInset = contentInset; + _contentOffset.x -= x; + _contentOffset.y -= y; + + [self _updateBounds]; + } +} + - (void)setContentSize:(CGSize)newSize { if (!CGSizeEqualToSize(newSize, _contentSize)) { @@ -375,33 +401,6 @@ - (BOOL)isTracking return NO; } -- (void)mouseMoved:(CGPoint)delta withEvent:(UIEvent *)event -{ - UITouch *touch = [[event allTouches] anyObject]; - const CGPoint point = [touch locationInView:self]; - const CGFloat scrollerSize = UIScrollerWidthForBoundsSize(self.bounds.size); - const BOOL shouldShowHorizontal = CGRectContainsPoint(CGRectInset(_horizontalScroller.frame, -scrollerSize, -scrollerSize), point); - const BOOL shouldShowVertical = CGRectContainsPoint(CGRectInset(_verticalScroller.frame, -scrollerSize, -scrollerSize), point); - const BOOL shouldShowScrollers = (shouldShowVertical || shouldShowHorizontal || _decelerating); - - _horizontalScroller.alwaysVisible = shouldShowScrollers; - _verticalScroller.alwaysVisible = shouldShowScrollers; - - [super mouseMoved:delta withEvent:event]; -} - -- (void)mouseExitedView:(UIView *)exited enteredView:(UIView *)entered withEvent:(UIEvent *)event -{ - if (!_decelerating) { - if ([exited isDescendantOfView:self] && ![entered isDescendantOfView:self]) { - _horizontalScroller.alwaysVisible = NO; - _verticalScroller.alwaysVisible = NO; - } - } - - [super mouseExitedView:exited enteredView:entered withEvent:event]; -} - - (UIScrollViewAnimation *)_pageSnapAnimation { const CGSize pageSize = self.bounds.size; @@ -428,11 +427,11 @@ - (UIScrollViewAnimation *)_pageSnapAnimation // quickly animate the snap (if necessary) if (!CGPointEqualToPoint(finalContentOffset, _contentOffset)) { - return [[[UIScrollViewAnimationScroll alloc] initWithScrollView:self + return [[UIScrollViewAnimationScroll alloc] initWithScrollView:self fromContentOffset:_contentOffset toContentOffset:finalContentOffset duration:UIScrollViewQuickAnimationDuration - curve:UIScrollViewAnimationScrollCurveQuadraticEaseOut] autorelease]; + curve:UIScrollViewAnimationScrollCurveQuadraticEaseOut]; } else { return nil; } @@ -452,8 +451,8 @@ - (UIScrollViewAnimation *)_decelerationAnimationWithVelocity:(CGPoint)velocity } if (!CGPointEqualToPoint(velocity, CGPointZero) || !CGPointEqualToPoint(confinedOffset, _contentOffset)) { - return [[[UIScrollViewAnimationDeceleration alloc] initWithScrollView:self - velocity:velocity] autorelease]; + return [[UIScrollViewAnimationDeceleration alloc] initWithScrollView:self + velocity:velocity]; } else { return nil; } @@ -475,11 +474,6 @@ - (void)_beginDragging } } -- (BOOL)isDragging -{ - return _dragging; -} - - (void)_endDraggingWithDecelerationVelocity:(CGPoint)velocity { if (_dragging) { @@ -598,9 +592,11 @@ - (void)_gestureDidChange:(UIGestureRecognizer *)gesture // messages can be preserved perfectly rather than trying to emulate them myself. this results // in a better feeling end product even if the bouncing at the edges isn't quite entirely right. // see notes in UIScrollViewAnimationDeceleration.m for more. - if ([_scrollAnimation respondsToSelector:@selector(momentumScrollBy:)]) { - [_scrollAnimation momentumScrollBy:delta]; - } + + // updated note: this used to be guarded by respondsToSelector: but I have instead added a blank + // implementation of -momentumScrollBy: to UIScrollAnimation's base class. If a specific animation + // cannot deal with a momentum scroll, then it will be ignored. + [_scrollAnimation momentumScrollBy:delta]; } else { CGPoint offset = self.contentOffset; offset.x += delta.x; @@ -645,11 +641,6 @@ - (void)_UIScrollerDidEndDragging:(UIScroller *)scroller withEvent:(UIEvent *)ev [self _endDraggingWithDecelerationVelocity:CGPointZero]; } -- (BOOL)isDecelerating -{ - return NO; -} - - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated { const CGRect contentRect = CGRectMake(0,0,_contentSize.width, _contentSize.height); @@ -728,4 +719,57 @@ - (NSString *)description return [NSString stringWithFormat:@"<%@: %p; frame = (%.0f %.0f; %.0f %.0f); clipsToBounds = %@; layer = %@; contentOffset = {%.0f, %.0f}>", [self className], self, self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height, (self.clipsToBounds ? @"YES" : @"NO"), self.layer, self.contentOffset.x, self.contentOffset.y]; } +// after some experimentation, it seems UIScrollView blocks or captures the touch events that fall through and +// I'm not entirely sure why, but something is certainly going on there so I'm replicating that here. since I +// suspect it's just stopping everything from going through, I'm also capturing and ignoring some of the +// mouse-related responder events added by Chameleon rather than passing them along the responder chain, too. +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ +} + +- (void)scrollWheelMoved:(CGPoint)delta withEvent:(UIEvent *)event +{ +} + +- (void)rightClick:(UITouch *)touch withEvent:(UIEvent *)event +{ +} + +- (void)mouseMoved:(UITouch *)touch withEvent:(UIEvent *)event +{ + const CGPoint point = [touch locationInView:self]; + const CGFloat scrollerSize = UIScrollerWidthForBoundsSize(self.bounds.size); + const BOOL shouldShowHorizontal = CGRectContainsPoint(CGRectInset(_horizontalScroller.frame, -scrollerSize, -scrollerSize), point); + const BOOL shouldShowVertical = CGRectContainsPoint(CGRectInset(_verticalScroller.frame, -scrollerSize, -scrollerSize), point); + const BOOL shouldShowScrollers = (shouldShowVertical || shouldShowHorizontal || _decelerating); + + _horizontalScroller.alwaysVisible = shouldShowScrollers; + _verticalScroller.alwaysVisible = shouldShowScrollers; +} + +- (void)mouseExited:(UIView *)view withEvent:(UIEvent *)event +{ + if (!_decelerating) { + _horizontalScroller.alwaysVisible = NO; + _verticalScroller.alwaysVisible = NO; + } +} + +- (id)mouseCursorForEvent:(UIEvent *)event +{ + return nil; +} + @end diff --git a/UIKit/Classes/UIScrollViewAnimation.h b/UIKit/Classes/UIScrollViewAnimation.h index 7432d428..a9406f1a 100644 --- a/UIKit/Classes/UIScrollViewAnimation.h +++ b/UIKit/Classes/UIScrollViewAnimation.h @@ -29,15 +29,13 @@ #import "UIScrollView+UIPrivate.h" -@interface UIScrollViewAnimation : NSObject { -@package - UIScrollView *scrollView; - NSTimeInterval beginTime; -} - +@interface UIScrollViewAnimation : NSObject - (id)initWithScrollView:(UIScrollView *)sv; - (BOOL)animate; +- (void)momentumScrollBy:(CGPoint)delta; +@property (nonatomic, readonly) UIScrollView *scrollView; +@property (nonatomic, assign) NSTimeInterval beginTime; @end extern CGFloat UILinearInterpolation(CGFloat t, CGFloat start, CGFloat end); diff --git a/UIKit/Classes/UIScrollViewAnimation.m b/UIKit/Classes/UIScrollViewAnimation.m index eb6d149f..1e8297f2 100644 --- a/UIKit/Classes/UIScrollViewAnimation.m +++ b/UIKit/Classes/UIScrollViewAnimation.m @@ -56,8 +56,8 @@ @implementation UIScrollViewAnimation - (id)initWithScrollView:(UIScrollView *)sv { if ((self=[super init])) { - scrollView = sv; - beginTime = [NSDate timeIntervalSinceReferenceDate]; + _scrollView = sv; + _beginTime = [NSDate timeIntervalSinceReferenceDate]; } return self; } @@ -67,4 +67,9 @@ - (BOOL)animate return YES; } +- (void)momentumScrollBy:(CGPoint)delta +{ + // does nothing +} + @end diff --git a/UIKit/Classes/UIScrollViewAnimationDeceleration.h b/UIKit/Classes/UIScrollViewAnimationDeceleration.h index 5f747acd..4f822180 100644 --- a/UIKit/Classes/UIScrollViewAnimationDeceleration.h +++ b/UIKit/Classes/UIScrollViewAnimationDeceleration.h @@ -38,15 +38,9 @@ typedef struct { BOOL bounced; } UIScrollViewAnimationDecelerationComponent; -@interface UIScrollViewAnimationDeceleration : UIScrollViewAnimation { - UIScrollViewAnimationDecelerationComponent x; - UIScrollViewAnimationDecelerationComponent y; - NSTimeInterval lastMomentumTime; -} - +@interface UIScrollViewAnimationDeceleration : UIScrollViewAnimation - (id)initWithScrollView:(UIScrollView *)sv velocity:(CGPoint)v; - (void)momentumScrollBy:(CGPoint)delta; - @end diff --git a/UIKit/Classes/UIScrollViewAnimationDeceleration.m b/UIKit/Classes/UIScrollViewAnimationDeceleration.m index dac17cab..7b27db7e 100644 --- a/UIKit/Classes/UIScrollViewAnimationDeceleration.m +++ b/UIKit/Classes/UIScrollViewAnimationDeceleration.m @@ -121,41 +121,45 @@ static BOOL BounceComponent(NSTimeInterval t, UIScrollViewAnimationDecelerationC } } -@implementation UIScrollViewAnimationDeceleration +@implementation UIScrollViewAnimationDeceleration { + UIScrollViewAnimationDecelerationComponent _x; + UIScrollViewAnimationDecelerationComponent _y; + NSTimeInterval _lastMomentumTime; +} - (id)initWithScrollView:(UIScrollView *)sv velocity:(CGPoint)v; { if ((self=[super initWithScrollView:sv])) { - lastMomentumTime = beginTime; - - x.decelerateTime = beginTime; - x.velocity = ClampedVelocty(v.x); - x.position = scrollView.contentOffset.x; - x.returnFrom = 0; - x.returnTime = 0; - x.bounced = NO; - - y.decelerateTime = beginTime; - y.velocity = ClampedVelocty(v.y); - y.position = scrollView.contentOffset.y; - y.returnFrom = 0; - y.returnTime = 0; - y.bounced = NO; + _lastMomentumTime = self.beginTime; + + _x.decelerateTime = self.beginTime; + _x.velocity = ClampedVelocty(v.x); + _x.position = self.scrollView.contentOffset.x; + _x.returnFrom = 0; + _x.returnTime = 0; + _x.bounced = NO; + + _y.decelerateTime = self.beginTime; + _y.velocity = ClampedVelocty(v.y); + _y.position = self.scrollView.contentOffset.y; + _y.returnFrom = 0; + _y.returnTime = 0; + _y.bounced = NO; // if the velocity is 0, we're going to assume we just need to return it back to position immediately // this works around the case where the content was already at an edge and the user just flicked in // such a way that it should bounce a bit and return to the proper offset. not doing something like this // (along with the associated code in UIScrollView) results in crazy forces being applied in those cases. - if (x.velocity == 0) { - x.bounced = YES; - x.returnTime = beginTime; - x.returnFrom = x.position; + if (_x.velocity == 0) { + _x.bounced = YES; + _x.returnTime = self.beginTime; + _x.returnFrom = _x.position; } - if (y.velocity == 0) { - y.bounced = YES; - y.returnTime = beginTime; - y.returnFrom = y.position; + if (_y.velocity == 0) { + _y.bounced = YES; + _y.returnTime = self.beginTime; + _y.returnFrom = _y.position; } } return self; @@ -164,40 +168,40 @@ - (id)initWithScrollView:(UIScrollView *)sv velocity:(CGPoint)v; - (BOOL)animate { const NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate]; - const BOOL isFinishedWaitingForMomentumScroll = ((currentTime - lastMomentumTime) > 0.15f); + const BOOL isFinishedWaitingForMomentumScroll = ((currentTime - _lastMomentumTime) > 0.15f); BOOL finished = NO; - while (!finished && currentTime >= beginTime) { - CGPoint confinedOffset = [scrollView _confinedContentOffset:CGPointMake(x.position, y.position)]; + while (!finished && currentTime >= self.beginTime) { + CGPoint confinedOffset = [self.scrollView _confinedContentOffset:CGPointMake(_x.position, _y.position)]; - const BOOL verticalIsFinished = BounceComponent(beginTime, &y, confinedOffset.y); - const BOOL horizontalIsFinished = BounceComponent(beginTime, &x, confinedOffset.x); + const BOOL verticalIsFinished = BounceComponent(self.beginTime, &_y, confinedOffset.y); + const BOOL horizontalIsFinished = BounceComponent(self.beginTime, &_x, confinedOffset.x); finished = (verticalIsFinished && horizontalIsFinished && isFinishedWaitingForMomentumScroll); - beginTime += physicsTimeStep; + self.beginTime += physicsTimeStep; } - [scrollView _setRestrainedContentOffset:CGPointMake(x.position, y.position)]; + [self.scrollView _setRestrainedContentOffset:CGPointMake(_x.position, _y.position)]; return finished; } - (void)momentumScrollBy:(CGPoint)delta { - lastMomentumTime = [NSDate timeIntervalSinceReferenceDate]; + _lastMomentumTime = [NSDate timeIntervalSinceReferenceDate]; - if (!x.bounced) { - x.position += delta.x; - x.velocity = ClampedVelocty(delta.x / (lastMomentumTime - x.decelerateTime)); - x.decelerateTime = lastMomentumTime; + if (!_x.bounced) { + _x.position += delta.x; + _x.velocity = ClampedVelocty(delta.x / (_lastMomentumTime - _x.decelerateTime)); + _x.decelerateTime = _lastMomentumTime; } - if (!y.bounced) { - y.position += delta.y; - y.velocity = ClampedVelocty(delta.y / (lastMomentumTime - y.decelerateTime)); - y.decelerateTime = lastMomentumTime; + if (!_y.bounced) { + _y.position += delta.y; + _y.velocity = ClampedVelocty(delta.y / (_lastMomentumTime - _y.decelerateTime)); + _y.decelerateTime = _lastMomentumTime; } } diff --git a/UIKit/Classes/UIScrollViewAnimationScroll.h b/UIKit/Classes/UIScrollViewAnimationScroll.h index c7b37c8e..4739063b 100644 --- a/UIKit/Classes/UIScrollViewAnimationScroll.h +++ b/UIKit/Classes/UIScrollViewAnimationScroll.h @@ -29,18 +29,16 @@ #import "UIScrollViewAnimation.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIScrollViewAnimationScrollCurve) { UIScrollViewAnimationScrollCurveLinear, UIScrollViewAnimationScrollCurveQuadraticEaseOut -} UIScrollViewAnimationScrollCurve; - -@interface UIScrollViewAnimationScroll : UIScrollViewAnimation { - CGPoint beginContentOffset; - CGPoint endContentOffset; - NSTimeInterval duration; - UIScrollViewAnimationScrollCurve curve; -} +}; +@interface UIScrollViewAnimationScroll : UIScrollViewAnimation - (id)initWithScrollView:(UIScrollView *)sv fromContentOffset:(CGPoint)from toContentOffset:(CGPoint)to duration:(NSTimeInterval)d curve:(UIScrollViewAnimationScrollCurve)c; +@property (nonatomic, readonly) CGPoint beginContentOffset; +@property (nonatomic, readonly) CGPoint endContentOffset; +@property (nonatomic, readonly) NSTimeInterval duration; +@property (nonatomic, readonly) UIScrollViewAnimationScrollCurve animationCurve; @end diff --git a/UIKit/Classes/UIScrollViewAnimationScroll.m b/UIKit/Classes/UIScrollViewAnimationScroll.m index 014bef36..255136d4 100644 --- a/UIKit/Classes/UIScrollViewAnimationScroll.m +++ b/UIKit/Classes/UIScrollViewAnimationScroll.m @@ -34,10 +34,10 @@ @implementation UIScrollViewAnimationScroll - (id)initWithScrollView:(UIScrollView *)sv fromContentOffset:(CGPoint)from toContentOffset:(CGPoint)to duration:(NSTimeInterval)d curve:(UIScrollViewAnimationScrollCurve)c { if ((self=[super initWithScrollView:sv])) { - beginContentOffset = from; - endContentOffset = to; - duration = d; - curve = c; + _beginContentOffset = from; + _endContentOffset = to; + _duration = d; + _animationCurve = c; } return self; } @@ -45,13 +45,13 @@ - (id)initWithScrollView:(UIScrollView *)sv fromContentOffset:(CGPoint)from toCo - (BOOL)animate { const NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate]; - const NSTimeInterval elapsedTime = currentTime - beginTime; - const CGFloat animationPosition = MIN(1, (elapsedTime / duration)); + const NSTimeInterval elapsedTime = currentTime - self.beginTime; + const CGFloat animationPosition = MIN(1, (elapsedTime / _duration)); - CGFloat (*curveFunction)(CGFloat t, CGFloat start, CGFloat end) = (curve == UIScrollViewAnimationScrollCurveLinear)? &UILinearInterpolation : &UIQuadraticEaseOut; + CGFloat (*curveFunction)(CGFloat t, CGFloat start, CGFloat end) = (_animationCurve == UIScrollViewAnimationScrollCurveLinear)? &UILinearInterpolation : &UIQuadraticEaseOut; - scrollView.contentOffset = CGPointMake(curveFunction(animationPosition, beginContentOffset.x, endContentOffset.x), - curveFunction(animationPosition, beginContentOffset.y, endContentOffset.y)); + self.scrollView.contentOffset = CGPointMake(curveFunction(animationPosition, _beginContentOffset.x, _endContentOffset.x), + curveFunction(animationPosition, _beginContentOffset.y, _endContentOffset.y)); return (animationPosition == 1); } diff --git a/UIKit/Classes/UIScrollWheelGestureRecognizer.h b/UIKit/Classes/UIScrollWheelGestureRecognizer.h index 2ce4063d..a06a2543 100644 --- a/UIKit/Classes/UIScrollWheelGestureRecognizer.h +++ b/UIKit/Classes/UIScrollWheelGestureRecognizer.h @@ -33,11 +33,6 @@ // Unlike UIPanGestureRecognizer, this is a discrete recognizer. It is also, // obviously, entirely non-standard. :) -@interface UIScrollWheelGestureRecognizer : UIGestureRecognizer { - CGPoint _translation; -} - +@interface UIScrollWheelGestureRecognizer : UIGestureRecognizer - (CGPoint)translationInView:(UIView *)view; -- (void)setTranslation:(CGPoint)translation inView:(UIView *)view; - @end diff --git a/UIKit/Classes/UIScrollWheelGestureRecognizer.m b/UIKit/Classes/UIScrollWheelGestureRecognizer.m index 9d6d1b03..2ade616e 100644 --- a/UIKit/Classes/UIScrollWheelGestureRecognizer.m +++ b/UIKit/Classes/UIScrollWheelGestureRecognizer.m @@ -29,27 +29,31 @@ #import "UIScrollWheelGestureRecognizer.h" #import "UIGestureRecognizerSubclass.h" -#import "UITouch+UIPrivate.h" -#import "UIEvent.h" +#import "UITouchEvent.h" +#import "UITouch.h" -@implementation UIScrollWheelGestureRecognizer +@implementation UIScrollWheelGestureRecognizer { + CGPoint _translation; +} - (CGPoint)translationInView:(UIView *)view { return _translation; } -- (void)setTranslation:(CGPoint)translation inView:(UIView *)view -{ - _translation = translation; -} - -- (void)_discreteGestures:(NSSet *)touches withEvent:(UIEvent *)event +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - UITouch *touch = [[event touchesForGestureRecognizer:self] anyObject]; - if (self.state == UIGestureRecognizerStatePossible && [touch _gesture] == _UITouchDiscreteGestureScrollWheel) { - [self setTranslation:[touch _delta] inView:touch.view]; - self.state = UIGestureRecognizerStateRecognized; + if (self.state == UIGestureRecognizerStatePossible) { + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + + if (touchEvent.touchEventGesture == UITouchEventGestureScrollWheel) { + _translation = touchEvent.translation; + self.state = UIGestureRecognizerStateRecognized; + } else { + self.state = UIGestureRecognizerStateFailed; + } + } } } diff --git a/UIKit/Classes/UIScroller.h b/UIKit/Classes/UIScroller.h index a46fbf8a..b65d824e 100644 --- a/UIKit/Classes/UIScroller.h +++ b/UIKit/Classes/UIScroller.h @@ -40,20 +40,7 @@ CGFloat UIScrollerWidthForBoundsSize(CGSize boundsSize); - (void)_UIScrollerDidEndDragging:(UIScroller *)scroller withEvent:(UIEvent *)event; @end -@interface UIScroller : UIView { -@private - __unsafe_unretained id<_UIScrollerDelegate> _delegate; - CGFloat _contentOffset; - CGFloat _contentSize; - CGFloat _dragOffset; - BOOL _draggingKnob; - BOOL _isVertical; - CGPoint _lastTouchLocation; - NSTimer *_holdTimer; - UIScrollViewIndicatorStyle _indicatorStyle; - NSTimer *_fadeTimer; - BOOL _alwaysVisible; -} +@interface UIScroller : UIView // NOTE: UIScroller set's its own alpha to 0 when it is created, so it is NOT visible by default! // the flash/quickFlash methods alter its own alpha in order to fade in/out, etc. diff --git a/UIKit/Classes/UIScroller.m b/UIKit/Classes/UIScroller.m index cd7c7da7..3d02540b 100644 --- a/UIKit/Classes/UIScroller.m +++ b/UIKit/Classes/UIScroller.m @@ -50,9 +50,14 @@ CGFloat UIScrollerWidthForBoundsSize(CGSize boundsSize) } -@implementation UIScroller -@synthesize delegate=_delegate, contentOffset=_contentOffset, contentSize=_contentSize; -@synthesize indicatorStyle=_indicatorStyle, alwaysVisible=_alwaysVisible; +@implementation UIScroller { + CGFloat _dragOffset; + BOOL _draggingKnob; + BOOL _isVertical; + CGPoint _lastTouchLocation; + NSTimer *_holdTimer; + NSTimer *_fadeTimer; +} - (id)initWithFrame:(CGRect)frame { @@ -77,7 +82,7 @@ - (void)_fadeOut [UIView animateWithDuration:0.33 delay:0 - options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionTransitionNone | UIViewAnimationOptionAllowUserInteraction + options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionTransitionNone | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState animations:^(void) { self.alpha = _UIScrollerMinimumAlpha; } @@ -97,7 +102,7 @@ - (void)_fadeIn [UIView animateWithDuration:0.33 delay:0 - options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionTransitionNone | UIViewAnimationOptionAllowUserInteraction + options:UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionTransitionNone | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState animations:^(void) { self.alpha = 1; } diff --git a/UIKit/Classes/UISearchBar.h b/UIKit/Classes/UISearchBar.h index 31350b1d..a6336fe7 100644 --- a/UIKit/Classes/UISearchBar.h +++ b/UIKit/Classes/UISearchBar.h @@ -38,23 +38,15 @@ @protocol UISearchBarDelegate; -@interface UISearchBar : UIView { - UITextField *_searchField; - BOOL _showsCancelButton; - __unsafe_unretained id _delegate; - NSString *_placeholder; -} - +@interface UISearchBar : UIView @property (nonatomic, copy) NSString *text; -@property (nonatomic,assign) id delegate; +@property (nonatomic, assign) id delegate; @property (nonatomic) BOOL showsCancelButton; -@property (nonatomic,copy) NSString *placeholder; - +@property (nonatomic, copy) NSString *placeholder; @end @protocol UISearchBarDelegate - @optional - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar; @@ -70,5 +62,4 @@ - (void)searchBarResultsListButtonClicked:(UISearchBar *)searchBar; - (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope; - @end diff --git a/UIKit/Classes/UISearchBar.m b/UIKit/Classes/UISearchBar.m index 4990b4f7..90fa4aff 100644 --- a/UIKit/Classes/UISearchBar.m +++ b/UIKit/Classes/UISearchBar.m @@ -35,8 +35,9 @@ #import "UISearchBar.h" -@implementation UISearchBar -@synthesize delegate=_delegate, showsCancelButton = _showsCancelButton, placeholder=_placeholder; +@implementation UISearchBar { + UITextField *_searchField; +} - (id)initWithFrame:(CGRect)frame { @@ -50,9 +51,6 @@ - (id)initWithFrame:(CGRect)frame - (void)dealloc { _delegate = nil; - [_placeholder release]; - [_searchField release]; - [super dealloc]; } - (NSString *)text diff --git a/UIKit/Classes/UISearchDisplayController.h b/UIKit/Classes/UISearchDisplayController.h index aa4406e2..a19fc66d 100644 --- a/UIKit/Classes/UISearchDisplayController.h +++ b/UIKit/Classes/UISearchDisplayController.h @@ -38,15 +38,7 @@ @class UISearchBar, UITableView, UIViewController, UIPopoverController; @protocol UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate; -@interface UISearchDisplayController : NSObject { - UIViewController *_viewController; - UISearchBar *_searchBar; - UITableView *_tableView; - __unsafe_unretained id _delegate; - __unsafe_unretained id _tableViewDataSource; - __unsafe_unretained id _tableViewDelegate; -} - +@interface UISearchDisplayController : NSObject - (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController; @property (nonatomic, assign) id delegate; @@ -57,16 +49,14 @@ @property (nonatomic, readonly) UISearchBar *searchBar; @property (nonatomic, readonly) UIViewController *searchContentsController; -@property (nonatomic,readonly) UITableView *searchResultsTableView; -@property (nonatomic,assign) id searchResultsDataSource; -@property (nonatomic,assign) id searchResultsDelegate; - +@property (nonatomic, readonly) UITableView *searchResultsTableView; +@property (nonatomic, assign) id searchResultsDataSource; +@property (nonatomic, assign) id searchResultsDelegate; @end @protocol UISearchDisplayDelegate - @optional // when we start/end showing the search UI @@ -88,5 +78,4 @@ // return YES to reload table. called when search string/option changes. convenience methods on top UISearchBar delegate methods - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString; - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption; - @end diff --git a/UIKit/Classes/UISearchDisplayController.m b/UIKit/Classes/UISearchDisplayController.m index 32bafaa6..457d216b 100644 --- a/UIKit/Classes/UISearchDisplayController.m +++ b/UIKit/Classes/UISearchDisplayController.m @@ -38,20 +38,22 @@ #import "UIViewController.h" -@implementation UISearchDisplayController - +@implementation UISearchDisplayController { + UIViewController *_viewController; + __unsafe_unretained UITableView *_tableView; + __unsafe_unretained id _tableViewDataSource; + __unsafe_unretained id _tableViewDelegate; +} @synthesize searchContentsController = _viewController; -@synthesize searchBar = _searchBar; @synthesize searchResultsTableView = _tableView; @synthesize searchResultsDataSource = _tableViewDataSource; @synthesize searchResultsDelegate = _tableViewDelegate; -@synthesize delegate = _delegate; - (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController { if ((self = [super init])) { - _searchBar = [searchBar retain]; - _viewController = [viewController retain]; + _searchBar = searchBar; + _viewController = viewController; } return self; } @@ -61,9 +63,6 @@ - (void)dealloc _delegate = nil; _tableViewDataSource = nil; _tableViewDelegate = nil; - [_searchBar release]; - [_viewController release]; - [super dealloc]; } - (BOOL)isActive diff --git a/UIKit/Classes/UISegmentedControl.h b/UIKit/Classes/UISegmentedControl.h index 81fc4b97..dbc41c1c 100644 --- a/UIKit/Classes/UISegmentedControl.h +++ b/UIKit/Classes/UISegmentedControl.h @@ -12,75 +12,46 @@ // - Setting item content offset is not supported #import "UIControl.h" -#import "UIImage.h" -#import "UIFont.h" -typedef enum { - UISegmentedControlStylePlain, // large plain - UISegmentedControlStyleBordered, // large bordered - UISegmentedControlStyleBar, // small button/nav bar style. tintable - UISegmentedControlStyleBezeled, // large bezeled style. tintable -} UISegmentedControlStyle; +@class UIImage; -enum { - UISegmentedControlNoSegment = -1 // segment index for no selected segment +typedef NS_ENUM(NSInteger, UISegmentedControlStyle) { + UISegmentedControlStylePlain, // large plain + UISegmentedControlStyleBordered, // large bordered + UISegmentedControlStyleBar, // small button/nav bar style. tintable + UISegmentedControlStyleBezeled, // large bezeled style. tintable }; -@interface UISegmentedControl : UIControl { - -@private - - NSMutableArray *_segments; - NSInteger _selectedSegmentIndex; - NSUInteger _numberOfSegments; - BOOL _momentary; - NSMutableDictionary *_segmentMeta; - - UIImage *_buttonImage; - UIImage *_highlightedButtonImage; - UIImage *_dividerImage; - UIImage *_highlightedDividerImage; - - UIFont *_font; - UIColor *_textColor; - UIColor *_disabledTextColor; - UIColor *_textShadowColor; - CGSize _textShadowOffset; - UIEdgeInsets _textEdgeInsets; +enum { + UISegmentedControlNoSegment = -1 // segment index for no selected segment +}; - UISegmentedControlStyle _segmentedControlStyle; - UIColor *_tintColor; -} +typedef NS_ENUM(NSInteger, UISegmentedControlSegment) { + UISegmentedControlSegmentAny = 0, + UISegmentedControlSegmentLeft = 1, + UISegmentedControlSegmentCenter = 2, + UISegmentedControlSegmentRight = 3, + UISegmentedControlSegmentAlone = 4, +}; +@interface UISegmentedControl : UIControl @property (nonatomic) UISegmentedControlStyle segmentedControlStyle; // stub -@property (nonatomic,retain) UIColor *tintColor; // stub +@property (nonatomic,strong) UIColor *tintColor; // stub @property (nonatomic, assign, readonly) NSUInteger numberOfSegments; @property (nonatomic, assign) NSInteger selectedSegmentIndex; @property (nonatomic, getter=isMomentary) BOOL momentary; - (id)initWithItems:(NSArray *)items; -//- (void)insertSegmentWithTitle:(NSString *)title atIndex:(NSUInteger)segment animated:(BOOL)animated; -//- (void)insertSegmentWithImage:(UIImage *)image atIndex:(NSUInteger)segment animated:(BOOL)animated; -//- (void)removeSegmentAtIndex:(NSUInteger)segment animated:(BOOL)animated; -//- (void)removeAllSegments; - - (void)setTitle:(NSString *)title forSegmentAtIndex:(NSUInteger)segment; - (NSString *)titleForSegmentAtIndex:(NSUInteger)segment; - (void)setImage:(UIImage *)image forSegmentAtIndex:(NSUInteger)segment; - (UIImage *)imageForSegmentAtIndex:(NSUInteger)segment; -//- (void)setWidth:(CGFloat)width forSegmentAtIndex:(NSUInteger)segment; -//- (CGFloat)widthForSegmentAtIndex:(NSUInteger)segment; - -//- (void)setContentOffset:(CGSize)offset forSegmentAtIndex:(NSUInteger)segment; -//- (CGSize)contentOffsetForSegmentAtIndex:(NSUInteger)segment; - - (void)setEnabled:(BOOL)enabled forSegmentAtIndex:(NSUInteger)segment; - (BOOL)isEnabledForSegmentAtIndex:(NSUInteger)segment; - (void)setTitleTextAttributes:(NSDictionary *)attributes forState:(UIControlState)state; - (NSDictionary *)titleTextAttributesForState:(UIControlState)state; - @end diff --git a/UIKit/Classes/UISegmentedControl.m b/UIKit/Classes/UISegmentedControl.m index ae1cb6fd..372552cb 100644 --- a/UIKit/Classes/UISegmentedControl.m +++ b/UIKit/Classes/UISegmentedControl.m @@ -11,64 +11,28 @@ #import "UIColor.h" #import "UIStringDrawing.h" #import "UIGraphics.h" +#import "UIImage.h" +#import "UIFont.h" static NSString *kSSSegmentedControlEnabledKey = @"enabled"; -@interface UISegmentedControl () -@property (nonatomic, retain) UIImage *buttonImage; -@property (nonatomic, retain) UIImage *highlightedButtonImage; -@property (nonatomic, retain) UIImage *dividerImage; -@property (nonatomic, retain) UIImage *highlightedDividerImage; - -@property (nonatomic, retain) UIFont *font; -@property (nonatomic, retain) UIColor *textColor; -@property (nonatomic, retain) UIColor *disabledTextColor; -@property (nonatomic, retain) UIColor *textShadowColor; -@property (nonatomic, assign) CGSize textShadowOffset; -@property (nonatomic, assign) UIEdgeInsets textEdgeInsets; - -- (NSMutableDictionary *)_metaForSegmentIndex:(NSUInteger)index; -- (id)_metaValueForKey:(NSString *)key segmentIndex:(NSUInteger)index; -- (void)_setMetaValue:(id)value forKey:(NSString *)key segmentIndex:(NSUInteger)index; -@end - -@implementation UISegmentedControl - -@synthesize numberOfSegments = _numberOfSegments; -@synthesize selectedSegmentIndex = _selectedSegmentIndex; -@synthesize momentary = _momentary; -@synthesize buttonImage = _buttonImage; -@synthesize highlightedButtonImage = _highlightedButtonImage; -@synthesize dividerImage = _dividerImage; -@synthesize highlightedDividerImage = _highlightedDividerImage; -@synthesize font = _font; -@synthesize textColor = _textColor; -@synthesize disabledTextColor = _disabledTextColor; -@synthesize textShadowColor = _textShadowColor; -@synthesize textShadowOffset = _textShadowOffset; -@synthesize textEdgeInsets = _textEdgeInsets; -@synthesize segmentedControlStyle = _segmentedControlStyle; -@synthesize tintColor = _tintColor; - -#pragma mark NSObject - -- (void)dealloc -{ - [_segments release]; - [_buttonImage release]; - [_highlightedButtonImage release]; - [_dividerImage release]; - [_highlightedDividerImage release]; - [_font release]; - [_textColor release]; - [_disabledTextColor release]; - [_textShadowColor release]; - [_segmentMeta release]; - [_tintColor release]; - [super dealloc]; +@implementation UISegmentedControl { + NSMutableArray *_segments; + NSMutableDictionary *_segmentMeta; + + UIImage *_buttonImage; + UIImage *_highlightedButtonImage; + UIImage *_dividerImage; + UIImage *_highlightedDividerImage; + + UIFont *_font; + UIColor *_textColor; + UIColor *_disabledTextColor; + UIColor *_textShadowColor; + CGSize _textShadowOffset; + UIEdgeInsets _textEdgeInsets; } - #pragma mark UIResponder - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event @@ -110,16 +74,16 @@ - (id)initWithFrame:(CGRect)frame _momentary = NO; // TODO: add images - self.buttonImage = [[UIImage imageNamed:@"UISegmentBarButton.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0]; - self.highlightedButtonImage = [[UIImage imageNamed:@"UISegmentBarButtonHighlighted.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0]; - self.dividerImage = [UIImage imageNamed:@"UISegmentBarDivider.png"]; - self.highlightedDividerImage = [UIImage imageNamed:@"UISegmentBarDividerHighlighted.png"]; + _buttonImage = [[UIImage imageNamed:@"UISegmentBarButton.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0]; + _highlightedButtonImage = [[UIImage imageNamed:@"UISegmentBarButtonHighlighted.png"] stretchableImageWithLeftCapWidth:6 topCapHeight:0]; + _dividerImage = [UIImage imageNamed:@"UISegmentBarDivider.png"]; + _highlightedDividerImage = [UIImage imageNamed:@"UISegmentBarDividerHighlighted.png"]; self.selectedSegmentIndex = UISegmentedControlNoSegment; - _font = [[UIFont boldSystemFontOfSize:12.0f] retain]; - _textColor = [[UIColor whiteColor] retain]; - _disabledTextColor = [[UIColor colorWithWhite:0.561f alpha:1.0f] retain]; - _textShadowColor = [[UIColor colorWithWhite:0.0f alpha:0.5f] retain]; + _font = [UIFont boldSystemFontOfSize:12.0f]; + _textColor = [UIColor whiteColor]; + _disabledTextColor = [UIColor colorWithWhite:0.561f alpha:1.0f]; + _textShadowColor = [UIColor colorWithWhite:0.0f alpha:0.5f]; _textShadowOffset = CGSizeMake(0.0f, -1.0f); _textEdgeInsets = UIEdgeInsetsMake(-1.0f, 0.0f, 0.0f, 0.0f); } diff --git a/UIKit/Classes/UISlider.h b/UIKit/Classes/UISlider.h index d3f76acb..f1fe6e35 100644 --- a/UIKit/Classes/UISlider.h +++ b/UIKit/Classes/UISlider.h @@ -37,14 +37,24 @@ @class UIImageView, UIImage; -@interface UISlider : UIControl { - float _value; - float _minimumValue; - float _maximumValue; -} +@interface UISlider : UIControl +- (UIImage *)minimumTrackImageForState:(UIControlState)state; +- (void)setMinimumTrackImage:(UIImage *)image forState:(UIControlState)state; +- (UIImage *)maximumTrackImageForState:(UIControlState)state; +- (void)setMaximumTrackImage:(UIImage *)image forState:(UIControlState)state; +- (UIImage *)thumbImageForState:(UIControlState)state; +- (void)setThumbImage:(UIImage *)image forState:(UIControlState)state; @property (nonatomic) float value; @property (nonatomic) float minimumValue; @property (nonatomic) float maximumValue; +@property (nonatomic, strong) UIImage *minimumValueImage; +@property (nonatomic, strong) UIImage *maximumValueImage; +@property (nonatomic, strong) UIColor *minimumTrackTintColor; +@property (nonatomic, readonly) UIImage *currentMinimumTrackImage; +@property (nonatomic, strong) UIColor *maximumTrackTintColor; +@property (nonatomic, readonly) UIImage *currentMaximumTrackImage; +@property (nonatomic, strong) UIColor *thumbTintColor; +@property (nonatomic, readonly) UIImage *currentThumbImage; @end diff --git a/UIKit/Classes/UISlider.m b/UIKit/Classes/UISlider.m index 349eadfa..7571c6d3 100644 --- a/UIKit/Classes/UISlider.m +++ b/UIKit/Classes/UISlider.m @@ -38,13 +38,51 @@ @implementation UISlider -@synthesize value = _value; -@synthesize minimumValue = _minimumValue; -@synthesize maximumValue = _maximumValue; - - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p; frame = (%.0f %.0f; %.0f %.0f); opaque = %@; layer = %@; value = %f>", [self className], self, self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height, (self.opaque ? @"YES" : @"NO"), self.layer, self.value]; } +- (UIImage *)minimumTrackImageForState:(UIControlState)state +{ + return nil; +} + +- (void)setMinimumTrackImage:(UIImage *)image forState:(UIControlState)state +{ +} + +- (UIImage *)maximumTrackImageForState:(UIControlState)state +{ + return nil; +} + +- (void)setMaximumTrackImage:(UIImage *)image forState:(UIControlState)state +{ +} + +- (UIImage *)thumbImageForState:(UIControlState)state +{ + return nil; +} + +- (void)setThumbImage:(UIImage *)image forState:(UIControlState)state +{ +} + +- (UIImage *)currentMinimumTrackImage +{ + return nil; +} + +- (UIImage *)currentMaximumTrackImage +{ + return nil; +} + +- (UIImage *)currentThumbImage +{ + return nil; +} + @end diff --git a/UIKit/Classes/UISplitViewController.h b/UIKit/Classes/UISplitViewController.h index 388d3d64..71670fa2 100644 --- a/UIKit/Classes/UISplitViewController.h +++ b/UIKit/Classes/UISplitViewController.h @@ -31,21 +31,9 @@ @protocol UISplitViewControllerDelegate; -@interface UISplitViewController : UIViewController { -@private - __unsafe_unretained id _delegate; - NSArray *_viewControllers; - - struct { - unsigned willPresentViewController : 1; - unsigned willHideViewController : 1; - unsigned willShowViewController : 1; - } _delegateHas; -} - +@interface UISplitViewController : UIViewController @property (nonatomic, assign) id delegate; @property (nonatomic, copy) NSArray *viewControllers; - @end @class UIPopoverController; diff --git a/UIKit/Classes/UISplitViewController.m b/UIKit/Classes/UISplitViewController.m index 384892a3..8152703b 100644 --- a/UIKit/Classes/UISplitViewController.m +++ b/UIKit/Classes/UISplitViewController.m @@ -28,7 +28,6 @@ */ #import "UISplitViewController.h" -#import "UIViewController+UIPrivate.h" #import "UIView.h" #import "UITouch.h" #import "UIColor.h" @@ -64,12 +63,6 @@ - (id)initWithFrame:(CGRect)frame return self; } -- (void)dealloc -{ - [leftPanel release]; - [rightPanel release]; - [super dealloc]; -} - (void)addViewControllers:(NSArray *)viewControllers { @@ -175,8 +168,13 @@ - (id)mouseCursorForEvent:(UIEvent *)event -@implementation UISplitViewController -@synthesize delegate=_delegate, viewControllers=_viewControllers; +@implementation UISplitViewController { + struct { + unsigned willPresentViewController : 1; + unsigned willHideViewController : 1; + unsigned willShowViewController : 1; + } _delegateHas; +} - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle { @@ -185,11 +183,6 @@ - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle return self; } -- (void)dealloc -{ - [_viewControllers release]; - [super dealloc]; -} - (void)setDelegate:(id )newDelegate { @@ -201,7 +194,7 @@ - (void)setDelegate:(id )newDelegate - (void)loadView { - self.view = [[[_UISplitViewControllerView alloc] initWithFrame:CGRectMake(0,0,1024,768)] autorelease]; + self.view = [[_UISplitViewControllerView alloc] initWithFrame:CGRectMake(0,0,1024,768)]; self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; } @@ -209,6 +202,7 @@ - (void)setViewControllers:(NSArray *)newControllers { assert([newControllers count]==2); + /* if (![newControllers isEqualToArray:_viewControllers]) { for (UIViewController *c in _viewControllers) { [c _setParentViewController:nil]; @@ -237,11 +231,12 @@ - (void)setViewControllers:(NSArray *)newControllers } } - [_viewControllers release]; _viewControllers = [newControllers copy]; } + */ } +/* - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; @@ -274,5 +269,6 @@ - (void)viewDidDisappear:(BOOL)animated [c viewDidDisappear:animated]; } } + */ @end diff --git a/UIKit/Classes/UIStringDrawing.h b/UIKit/Classes/UIStringDrawing.h index c8b7d909..493bc929 100644 --- a/UIKit/Classes/UIStringDrawing.h +++ b/UIKit/Classes/UIStringDrawing.h @@ -29,31 +29,31 @@ #import -typedef enum { +typedef NS_ENUM(NSInteger, UILineBreakMode) { UILineBreakModeWordWrap = 0, UILineBreakModeCharacterWrap, UILineBreakModeClip, UILineBreakModeHeadTruncation, UILineBreakModeTailTruncation, UILineBreakModeMiddleTruncation, -} UILineBreakMode; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITextAlignment) { UITextAlignmentLeft, UITextAlignmentCenter, UITextAlignmentRight, -} UITextAlignment; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIBaselineAdjustment) { UIBaselineAdjustmentAlignBaselines, UIBaselineAdjustmentAlignCenters, UIBaselineAdjustmentNone, -} UIBaselineAdjustment; +}; -NSString *const UITextAttributeFont; -NSString *const UITextAttributeTextColor; -NSString *const UITextAttributeTextShadowColor; -NSString *const UITextAttributeTextShadowOffset; +extern NSString *const UITextAttributeFont; +extern NSString *const UITextAttributeTextColor; +extern NSString *const UITextAttributeTextShadowColor; +extern NSString *const UITextAttributeTextShadowOffset; @class UIFont; diff --git a/UIKit/Classes/UISwipeGestureRecognizer.h b/UIKit/Classes/UISwipeGestureRecognizer.h index ff3304a8..47f87fff 100644 --- a/UIKit/Classes/UISwipeGestureRecognizer.h +++ b/UIKit/Classes/UISwipeGestureRecognizer.h @@ -29,19 +29,17 @@ #import "UIGestureRecognizer.h" -typedef enum { +// OSX's native swipe gesture doesn't seem to support the idea of varying numbers of touches involved in +// the gesture, so this will recognize for any OSX swipe regardless of touch count! + +typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) { UISwipeGestureRecognizerDirectionRight = 1 << 0, UISwipeGestureRecognizerDirectionLeft = 1 << 1, UISwipeGestureRecognizerDirectionUp = 1 << 2, UISwipeGestureRecognizerDirectionDown = 1 << 3 -} UISwipeGestureRecognizerDirection; - -@interface UISwipeGestureRecognizer : UIGestureRecognizer { - UISwipeGestureRecognizerDirection _direction; - NSUInteger _numberOfTouchesRequired; -} +}; +@interface UISwipeGestureRecognizer : UIGestureRecognizer @property (nonatomic) UISwipeGestureRecognizerDirection direction; @property (nonatomic) NSUInteger numberOfTouchesRequired; - @end diff --git a/UIKit/Classes/UISwipeGestureRecognizer.m b/UIKit/Classes/UISwipeGestureRecognizer.m index 08a7e86f..689eb031 100644 --- a/UIKit/Classes/UISwipeGestureRecognizer.m +++ b/UIKit/Classes/UISwipeGestureRecognizer.m @@ -29,9 +29,9 @@ #import "UISwipeGestureRecognizer.h" #import "UIGestureRecognizerSubclass.h" +#import "UITouchEvent.h" @implementation UISwipeGestureRecognizer -@synthesize direction=_direction, numberOfTouchesRequired=_numberOfTouchesRequired; - (id)initWithTarget:(id)target action:(SEL)action { @@ -42,4 +42,29 @@ - (id)initWithTarget:(id)target action:(SEL)action return self; } +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (self.state == UIGestureRecognizerStatePossible) { + if ([event isKindOfClass:[UITouchEvent class]]) { + UITouchEvent *touchEvent = (UITouchEvent *)event; + + if (touchEvent.touchEventGesture == UITouchEventGestureSwipe) { + if (_direction == UISwipeGestureRecognizerDirectionLeft && touchEvent.translation.x > 0) { + self.state = UIGestureRecognizerStateRecognized; + } else if (_direction == UISwipeGestureRecognizerDirectionRight && touchEvent.translation.x < 0) { + self.state = UIGestureRecognizerStateRecognized; + } else if (_direction == UISwipeGestureRecognizerDirectionUp && touchEvent.translation.y > 0) { + self.state = UIGestureRecognizerStateRecognized; + } else if (_direction == UISwipeGestureRecognizerDirectionDown && touchEvent.translation.y < 0) { + self.state = UIGestureRecognizerStateRecognized; + } else { + self.state = UIGestureRecognizerStateFailed; + } + } else { + self.state = UIGestureRecognizerStateFailed; + } + } + } +} + @end diff --git a/UIKit/Classes/UISwitch.h b/UIKit/Classes/UISwitch.h index 93844054..87b276b5 100644 --- a/UIKit/Classes/UISwitch.h +++ b/UIKit/Classes/UISwitch.h @@ -29,13 +29,9 @@ #import "UIControl.h" -@interface UISwitch : UIControl { - BOOL _on; -} - +@interface UISwitch : UIControl - (id)initWithFrame:(CGRect)frame; - (void)setOn:(BOOL)on animated:(BOOL)animated; @property(nonatomic, getter=isOn) BOOL on; - @end diff --git a/UIKit/Classes/UISwitch.m b/UIKit/Classes/UISwitch.m index 2f80778c..b5434534 100644 --- a/UIKit/Classes/UISwitch.m +++ b/UIKit/Classes/UISwitch.m @@ -30,7 +30,6 @@ #import "UISwitch.h" @implementation UISwitch -@synthesize on = _on; - (id)initWithFrame:(CGRect)frame { diff --git a/UIKit/Classes/UITabBar.h b/UIKit/Classes/UITabBar.h index 9f0b43b7..4dfc9460 100644 --- a/UIKit/Classes/UITabBar.h +++ b/UIKit/Classes/UITabBar.h @@ -51,21 +51,13 @@ @end -@interface UITabBar : UIView { - __unsafe_unretained id _delegate; - NSArray *_items; - NSInteger _selectedItemIndex; -} - -@property (nonatomic, assign) id delegate; -@property (nonatomic, copy) NSArray *items; -@property (nonatomic, assign) UITabBarItem *selectedItem; - +@interface UITabBar : UIView - (void)setItems:(NSArray *)items animated:(BOOL)animated; - -// stub - (void)beginCustomizingItems:(NSArray *)items; - (BOOL)endCustomizingAnimated:(BOOL)animated; - (BOOL)isCustomizing; +@property (nonatomic, assign) id delegate; +@property (nonatomic, copy) NSArray *items; +@property (nonatomic, assign) UITabBarItem *selectedItem; @end diff --git a/UIKit/Classes/UITabBar.m b/UIKit/Classes/UITabBar.m index 9a2bc699..8b4a5b83 100644 --- a/UIKit/Classes/UITabBar.m +++ b/UIKit/Classes/UITabBar.m @@ -40,9 +40,9 @@ #define TABBAR_HEIGHT 60.0 -@implementation UITabBar - -@synthesize items = _items, delegate = _delegate; +@implementation UITabBar { + NSInteger _selectedItemIndex; +} - (id)initWithFrame:(CGRect)rect { @@ -50,7 +50,7 @@ - (id)initWithFrame:(CGRect)rect rect.size.height = TABBAR_HEIGHT; // tabbar is always fixed _selectedItemIndex = -1; UIImage *backgroundImage = [UIImage _popoverBackgroundImage]; - UIImageView *backgroundView = [[[UIImageView alloc] initWithImage:backgroundImage] autorelease]; + UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage]; backgroundView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; backgroundView.frame = rect; [self addSubview:backgroundView]; @@ -58,13 +58,6 @@ - (id)initWithFrame:(CGRect)rect return self; } -- (void)dealloc -{ - _delegate = nil; - [_items release]; - [super dealloc]; -} - - (UITabBarItem *)selectedItem { if (_selectedItemIndex >= 0) { diff --git a/UIKit/Classes/UITabBarController.h b/UIKit/Classes/UITabBarController.h index 2fb7dc07..bbd54404 100644 --- a/UIKit/Classes/UITabBarController.h +++ b/UIKit/Classes/UITabBarController.h @@ -41,18 +41,11 @@ @end @class UITabBar; -@interface UITabBarController : UIViewController { - UITabBar *_tabBar; - __unsafe_unretained UIViewController *_selectedViewController; - NSArray *_viewControllers; - NSUInteger _selectedIndex; -} - +@interface UITabBarController : UIViewController - (void)setViewControllers:(NSArray *)viewController animated:(BOOL)animated; @property (nonatomic, assign) UIViewController *selectedViewController; @property (nonatomic, copy) NSArray *viewControllers; @property (nonatomic, assign) NSUInteger selectedIndex; @property (nonatomic, readonly) UITabBar *tabBar; - @end diff --git a/UIKit/Classes/UITabBarController.m b/UIKit/Classes/UITabBarController.m index a37ef105..5c51d91e 100644 --- a/UIKit/Classes/UITabBarController.m +++ b/UIKit/Classes/UITabBarController.m @@ -32,11 +32,6 @@ @implementation UITabBarController -@synthesize selectedViewController = _selectedViewController; -@synthesize viewControllers = _viewControllers; -@synthesize selectedIndex = _selectedIndex; -@synthesize tabBar = _tabBar; - - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle { if ((self = [super initWithNibName:nibName bundle:nibBundle])) { @@ -45,11 +40,6 @@ - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle return self; } -- (void)dealloc -{ - [_tabBar release]; - [super dealloc]; -} - (void)setViewControllers:(NSArray *)viewController animated:(BOOL)animated { diff --git a/UIKit/Classes/UITabBarItem.h b/UIKit/Classes/UITabBarItem.h index a7c1bde7..7f49de64 100644 --- a/UIKit/Classes/UITabBarItem.h +++ b/UIKit/Classes/UITabBarItem.h @@ -37,7 +37,7 @@ @class UIImage; -typedef enum { +typedef NS_ENUM(NSInteger, UITabBarSystemItem) { UITabBarSystemItemMore, UITabBarSystemItemFavorites, UITabBarSystemItemFeatured, @@ -50,16 +50,12 @@ typedef enum { UITabBarSystemItemDownloads, UITabBarSystemItemMostRecent, UITabBarSystemItemMostViewed, -} UITabBarSystemItem; +}; -@interface UITabBarItem : UIBarItem { - NSString *_badgeValue; -} - +@interface UITabBarItem : UIBarItem - (id)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag; - (id)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag; @property (nonatomic, copy) NSString *badgeValue; - @end diff --git a/UIKit/Classes/UITabBarItem.m b/UIKit/Classes/UITabBarItem.m index 6672b43d..b8fb492b 100644 --- a/UIKit/Classes/UITabBarItem.m +++ b/UIKit/Classes/UITabBarItem.m @@ -37,7 +37,6 @@ #import "UIImage.h" @implementation UITabBarItem -@synthesize badgeValue=_badgeValue; - (id)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag { @@ -55,10 +54,4 @@ - (id)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag return self; } -- (void)dealloc -{ - [_badgeValue release]; - [super dealloc]; -} - @end diff --git a/UIKit/Classes/UITableView.h b/UIKit/Classes/UITableView.h index a6bdfb7b..93eb6272 100644 --- a/UIKit/Classes/UITableView.h +++ b/UIKit/Classes/UITableView.h @@ -66,76 +66,33 @@ extern NSString *const UITableViewIndexSearch; - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath; @end -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewStyle) { UITableViewStylePlain, UITableViewStyleGrouped -} UITableViewStyle; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewScrollPosition) { UITableViewScrollPositionNone, UITableViewScrollPositionTop, UITableViewScrollPositionMiddle, UITableViewScrollPositionBottom -} UITableViewScrollPosition; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewRowAnimation) { UITableViewRowAnimationFade, UITableViewRowAnimationRight, UITableViewRowAnimationLeft, UITableViewRowAnimationTop, UITableViewRowAnimationBottom, UITableViewRowAnimationNone, - UITableViewRowAnimationMiddle -} UITableViewRowAnimation; - -@interface UITableView : UIScrollView { -@private - UITableViewStyle _style; - __unsafe_unretained id _dataSource; - BOOL _needsReload; - CGFloat _rowHeight; - UIColor *_separatorColor; - UITableViewCellSeparatorStyle _separatorStyle; - UIView *_tableHeaderView; - UIView *_tableFooterView; - UIView *_backgroundView; - BOOL _allowsSelection; - BOOL _allowsSelectionDuringEditing; - BOOL _editing; - NSIndexPath *_selectedRow; - NSIndexPath *_highlightedRow; - NSMutableDictionary *_cachedCells; - NSMutableSet *_reusableCells; - NSMutableArray *_sections; - CGFloat _sectionHeaderHeight; - CGFloat _sectionFooterHeight; - - struct { - unsigned heightForRowAtIndexPath : 1; - unsigned heightForHeaderInSection : 1; - unsigned heightForFooterInSection : 1; - unsigned viewForHeaderInSection : 1; - unsigned viewForFooterInSection : 1; - unsigned willSelectRowAtIndexPath : 1; - unsigned didSelectRowAtIndexPath : 1; - unsigned willDeselectRowAtIndexPath : 1; - unsigned didDeselectRowAtIndexPath : 1; - unsigned willBeginEditingRowAtIndexPath : 1; - unsigned didEndEditingRowAtIndexPath : 1; - unsigned titleForDeleteConfirmationButtonForRowAtIndexPath: 1; - } _delegateHas; - - struct { - unsigned numberOfSectionsInTableView : 1; - unsigned titleForHeaderInSection : 1; - unsigned titleForFooterInSection : 1; - unsigned commitEditingStyle : 1; - unsigned canEditRowAtIndexPath : 1; - } _dataSourceHas; -} + UITableViewRowAnimationMiddle, + UITableViewRowAnimationAutomatic = 100 +}; +@interface UITableView : UIScrollView - (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style; - (void)reloadData; +- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; - (NSInteger)numberOfSections; - (NSInteger)numberOfRowsInSection:(NSInteger)section; - (NSArray *)indexPathsForRowsInRect:(CGRect)rect; @@ -174,14 +131,13 @@ typedef enum { @property (nonatomic, assign) id dataSource; @property (nonatomic) CGFloat rowHeight; @property (nonatomic) UITableViewCellSeparatorStyle separatorStyle; -@property (nonatomic, retain) UIColor *separatorColor; -@property (nonatomic, retain) UIView *tableHeaderView; -@property (nonatomic, retain) UIView *tableFooterView; -@property (nonatomic, retain) UIView *backgroundView; +@property (nonatomic, strong) UIColor *separatorColor; +@property (nonatomic, strong) UIView *tableHeaderView; +@property (nonatomic, strong) UIView *tableFooterView; +@property (nonatomic, strong) UIView *backgroundView; @property (nonatomic) BOOL allowsSelection; @property (nonatomic) BOOL allowsSelectionDuringEditing; // not implemented @property (nonatomic, getter=isEditing) BOOL editing; @property (nonatomic) CGFloat sectionHeaderHeight; @property (nonatomic) CGFloat sectionFooterHeight; - @end diff --git a/UIKit/Classes/UITableView.m b/UIKit/Classes/UITableView.m index 119c1ca0..8adb6151 100644 --- a/UIKit/Classes/UITableView.m +++ b/UIKit/Classes/UITableView.m @@ -36,7 +36,7 @@ #import "UIScreenAppKitIntegration.h" #import "UIWindow.h" #import "UIKitView.h" -#import "UIApplication+UIPrivate.h" +#import "UIApplicationAppKitIntegration.h" #import #import #import @@ -46,16 +46,37 @@ const CGFloat _UITableViewDefaultRowHeight = 43; -@interface UITableView () -- (void)_setNeedsReload; -@end - -@implementation UITableView -@synthesize style=_style, dataSource=_dataSource, rowHeight=_rowHeight, separatorStyle=_separatorStyle, separatorColor=_separatorColor; -@synthesize tableHeaderView=_tableHeaderView, tableFooterView=_tableFooterView, allowsSelection=_allowsSelection, editing=_editing; -@synthesize sectionFooterHeight=_sectionFooterHeight, sectionHeaderHeight=_sectionHeaderHeight; -@synthesize allowsSelectionDuringEditing=_allowsSelectionDuringEditing, backgroundView=_backgroundView; -@dynamic delegate; +@implementation UITableView { + BOOL _needsReload; + NSIndexPath *_selectedRow; + NSIndexPath *_highlightedRow; + NSMutableDictionary *_cachedCells; + NSMutableSet *_reusableCells; + NSMutableArray *_sections; + + struct { + unsigned heightForRowAtIndexPath : 1; + unsigned heightForHeaderInSection : 1; + unsigned heightForFooterInSection : 1; + unsigned viewForHeaderInSection : 1; + unsigned viewForFooterInSection : 1; + unsigned willSelectRowAtIndexPath : 1; + unsigned didSelectRowAtIndexPath : 1; + unsigned willDeselectRowAtIndexPath : 1; + unsigned didDeselectRowAtIndexPath : 1; + unsigned willBeginEditingRowAtIndexPath : 1; + unsigned didEndEditingRowAtIndexPath : 1; + unsigned titleForDeleteConfirmationButtonForRowAtIndexPath: 1; + } _delegateHas; + + struct { + unsigned numberOfSectionsInTableView : 1; + unsigned titleForHeaderInSection : 1; + unsigned titleForFooterInSection : 1; + unsigned commitEditingStyle : 1; + unsigned canEditRowAtIndexPath : 1; + } _dataSourceHas; +} - (id)initWithFrame:(CGRect)frame { @@ -87,18 +108,6 @@ - (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)theStyle return self; } -- (void)dealloc -{ - [_selectedRow release]; - [_highlightedRow release]; - [_tableFooterView release]; - [_tableHeaderView release]; - [_cachedCells release]; - [_sections release]; - [_reusableCells release]; - [_separatorColor release]; - [super dealloc]; -} - (void)setDataSource:(id)newSource { @@ -117,18 +126,18 @@ - (void)setDelegate:(id)newDelegate { [super setDelegate:newDelegate]; - _delegateHas.heightForRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)]; - _delegateHas.heightForHeaderInSection = [_delegate respondsToSelector:@selector(tableView:heightForHeaderInSection:)]; - _delegateHas.heightForFooterInSection = [_delegate respondsToSelector:@selector(tableView:heightForFooterInSection:)]; - _delegateHas.viewForHeaderInSection = [_delegate respondsToSelector:@selector(tableView:viewForHeaderInSection:)]; - _delegateHas.viewForFooterInSection = [_delegate respondsToSelector:@selector(tableView:viewForFooterInSection:)]; - _delegateHas.willSelectRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:willSelectRowAtIndexPath:)]; - _delegateHas.didSelectRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]; - _delegateHas.willDeselectRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:willDeselectRowAtIndexPath:)]; - _delegateHas.didDeselectRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:didDeselectRowAtIndexPath:)]; - _delegateHas.willBeginEditingRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:willBeginEditingRowAtIndexPath:)]; - _delegateHas.didEndEditingRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:didEndEditingRowAtIndexPath:)]; - _delegateHas.titleForDeleteConfirmationButtonForRowAtIndexPath = [_delegate respondsToSelector:@selector(tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:)]; + _delegateHas.heightForRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)]; + _delegateHas.heightForHeaderInSection = [newDelegate respondsToSelector:@selector(tableView:heightForHeaderInSection:)]; + _delegateHas.heightForFooterInSection = [newDelegate respondsToSelector:@selector(tableView:heightForFooterInSection:)]; + _delegateHas.viewForHeaderInSection = [newDelegate respondsToSelector:@selector(tableView:viewForHeaderInSection:)]; + _delegateHas.viewForFooterInSection = [newDelegate respondsToSelector:@selector(tableView:viewForFooterInSection:)]; + _delegateHas.willSelectRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:willSelectRowAtIndexPath:)]; + _delegateHas.didSelectRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]; + _delegateHas.willDeselectRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:willDeselectRowAtIndexPath:)]; + _delegateHas.didDeselectRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:didDeselectRowAtIndexPath:)]; + _delegateHas.willBeginEditingRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:willBeginEditingRowAtIndexPath:)]; + _delegateHas.didEndEditingRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:didEndEditingRowAtIndexPath:)]; + _delegateHas.titleForDeleteConfirmationButtonForRowAtIndexPath = [newDelegate respondsToSelector:@selector(tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:)]; } - (void)setRowHeight:(CGFloat)newHeight @@ -161,36 +170,37 @@ - (void)_updateSectionsCache const NSInteger numberOfRowsInSection = [self numberOfRowsInSection:section]; UITableViewSection *sectionRecord = [[UITableViewSection alloc] init]; - sectionRecord.headerView = _delegateHas.viewForHeaderInSection? [self.delegate tableView:self viewForHeaderInSection:section] : nil; - sectionRecord.footerView = _delegateHas.viewForFooterInSection? [self.delegate tableView:self viewForFooterInSection:section] : nil; sectionRecord.headerTitle = _dataSourceHas.titleForHeaderInSection? [self.dataSource tableView:self titleForHeaderInSection:section] : nil; sectionRecord.footerTitle = _dataSourceHas.titleForFooterInSection? [self.dataSource tableView:self titleForFooterInSection:section] : nil; + sectionRecord.headerHeight = _delegateHas.heightForHeaderInSection? [self.delegate tableView:self heightForHeaderInSection:section] : _sectionHeaderHeight; + sectionRecord.footerHeight = _delegateHas.heightForFooterInSection ? [self.delegate tableView:self heightForFooterInSection:section] : _sectionFooterHeight; + + sectionRecord.headerView = (sectionRecord.headerHeight > 0 && _delegateHas.viewForHeaderInSection)? [self.delegate tableView:self viewForHeaderInSection:section] : nil; + sectionRecord.footerView = (sectionRecord.footerHeight > 0 && _delegateHas.viewForFooterInSection)? [self.delegate tableView:self viewForFooterInSection:section] : nil; + // make a default section header view if there's a title for it and no overriding view - if (!sectionRecord.headerView && sectionRecord.headerTitle) { + if (!sectionRecord.headerView && sectionRecord.headerHeight > 0 && sectionRecord.headerTitle) { sectionRecord.headerView = [UITableViewSectionLabel sectionLabelWithTitle:sectionRecord.headerTitle]; } // make a default section footer view if there's a title for it and no overriding view - if (!sectionRecord.footerView && sectionRecord.footerTitle) { + if (!sectionRecord.footerView && sectionRecord.footerHeight > 0 && sectionRecord.footerTitle) { sectionRecord.footerView = [UITableViewSectionLabel sectionLabelWithTitle:sectionRecord.footerTitle]; } - - // if there's a view, then we need to set the height, otherwise it's going to be zero + if (sectionRecord.headerView) { [self addSubview:sectionRecord.headerView]; - sectionRecord.headerHeight = _delegateHas.heightForHeaderInSection? [self.delegate tableView:self heightForHeaderInSection:section] : _sectionHeaderHeight; } else { sectionRecord.headerHeight = 0; } if (sectionRecord.footerView) { [self addSubview:sectionRecord.footerView]; - sectionRecord.footerHeight = _delegateHas.heightForFooterInSection? [self.delegate tableView:self heightForFooterInSection:section] : _sectionFooterHeight; } else { sectionRecord.footerHeight = 0; } - + CGFloat *rowHeights = malloc(numberOfRowsInSection * sizeof(CGFloat)); CGFloat totalRowsHeight = 0; @@ -205,7 +215,6 @@ - (void)_updateSectionsCache free(rowHeights); [_sections addObject:sectionRecord]; - [sectionRecord release]; } } } @@ -315,7 +324,6 @@ - (void)_layoutTableView } // non-reusable cells should end up dealloced after at this point, but reusable ones live on in _reusableCells. - [availableCells release]; // now make sure that all available (but unused) reusable cells aren't on screen in the visible area. // this is done becaue when resizing a table view by shrinking it's height in an animation, it looks better. The reason is that @@ -456,7 +464,7 @@ - (NSArray *)indexPathsForRowsInRect:(CGRect)rect offset += sectionRecord.footerHeight; } - return [results autorelease]; + return results; } - (NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point @@ -487,7 +495,7 @@ - (NSArray *)indexPathsForVisibleRows - (NSArray *)visibleCells { - NSMutableArray *cells = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray *cells = [[NSMutableArray alloc] init]; for (NSIndexPath *index in [self indexPathsForVisibleRows]) { UITableViewCell *cell = [self cellForRowAtIndexPath:index]; if (cell) { @@ -501,8 +509,7 @@ - (void)setTableHeaderView:(UIView *)newHeader { if (newHeader != _tableHeaderView) { [_tableHeaderView removeFromSuperview]; - [_tableHeaderView release]; - _tableHeaderView = [newHeader retain]; + _tableHeaderView = newHeader; [self _setContentSize]; [self addSubview:_tableHeaderView]; } @@ -512,8 +519,7 @@ - (void)setTableFooterView:(UIView *)newFooter { if (newFooter != _tableFooterView) { [_tableFooterView removeFromSuperview]; - [_tableFooterView release]; - _tableFooterView = [newFooter retain]; + _tableFooterView = newFooter; [self _setContentSize]; [self addSubview:_tableFooterView]; } @@ -523,8 +529,7 @@ - (void)setBackgroundView:(UIView *)backgroundView { if (_backgroundView != backgroundView) { [_backgroundView removeFromSuperview]; - [_backgroundView release]; - _backgroundView = [backgroundView retain]; + _backgroundView = backgroundView; [self insertSubview:_backgroundView atIndex:0]; } } @@ -552,9 +557,7 @@ - (void)reloadData [_cachedCells removeAllObjects]; // clear prior selection - [_selectedRow release]; _selectedRow = nil; - [_highlightedRow release]; _highlightedRow = nil; // trigger the section cache to be repopulated @@ -564,6 +567,11 @@ - (void)reloadData _needsReload = NO; } +- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation +{ + [self reloadData]; +} + - (void)_reloadDataIfNeeded { if (_needsReload) { @@ -601,14 +609,14 @@ - (void)setFrame:(CGRect)frame - (NSIndexPath *)indexPathForSelectedRow { - return [[_selectedRow retain] autorelease]; + return _selectedRow; } - (NSIndexPath *)indexPathForCell:(UITableViewCell *)cell { for (NSIndexPath *index in [_cachedCells allKeys]) { if ([_cachedCells objectForKey:index] == cell) { - return [[index retain] autorelease]; + return index; } } @@ -619,7 +627,6 @@ - (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated { if (indexPath && [indexPath isEqual:_selectedRow]) { [self cellForRowAtIndexPath:_selectedRow].selected = NO; - [_selectedRow release]; _selectedRow = nil; } } @@ -633,8 +640,7 @@ - (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated sc if (![_selectedRow isEqual:indexPath]) { [self deselectRowAtIndexPath:_selectedRow animated:animated]; - [_selectedRow release]; - _selectedRow = [indexPath retain]; + _selectedRow = indexPath; [self cellForRowAtIndexPath:_selectedRow].selected = YES; } @@ -643,6 +649,35 @@ - (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated sc [self scrollToRowAtIndexPath:_selectedRow atScrollPosition:scrollPosition animated:animated]; } +- (void)_setUserSelectedRowAtIndexPath:(NSIndexPath *)rowToSelect +{ + if (_delegateHas.willSelectRowAtIndexPath) { + rowToSelect = [self.delegate tableView:self willSelectRowAtIndexPath:rowToSelect]; + } + + NSIndexPath *selectedRow = [self indexPathForSelectedRow]; + + if (selectedRow && ![selectedRow isEqual:rowToSelect]) { + NSIndexPath *rowToDeselect = selectedRow; + + if (_delegateHas.willDeselectRowAtIndexPath) { + rowToDeselect = [self.delegate tableView:self willDeselectRowAtIndexPath:rowToDeselect]; + } + + [self deselectRowAtIndexPath:rowToDeselect animated:NO]; + + if (_delegateHas.didDeselectRowAtIndexPath) { + [self.delegate tableView:self didDeselectRowAtIndexPath:rowToDeselect]; + } + } + + [self selectRowAtIndexPath:rowToSelect animated:NO scrollPosition:UITableViewScrollPositionNone]; + + if (_delegateHas.didSelectRowAtIndexPath) { + [self.delegate tableView:self didSelectRowAtIndexPath:rowToSelect]; + } +} + - (void)_scrollRectToVisible:(CGRect)aRect atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated { if (!CGRectIsNull(aRect) && aRect.size.height > 0) { @@ -684,10 +719,15 @@ - (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier { for (UITableViewCell *cell in _reusableCells) { if ([cell.reuseIdentifier isEqualToString:identifier]) { - [cell retain]; + UITableViewCell *strongCell = cell; + + // the above strongCell reference seems totally unnecessary, but without it ARC apparently + // ends up releasing the cell when it's removed on this line even though we're referencing it + // later in this method by way of the cell variable. I do not like this. [_reusableCells removeObject:cell]; - [cell prepareForReuse]; - return [cell autorelease]; + + [strongCell prepareForReuse]; + return strongCell; } } @@ -726,63 +766,25 @@ - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableVi - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { - if (!_highlightedRow) { - UITouch *touch = [touches anyObject]; - const CGPoint location = [touch locationInView:self]; - - _highlightedRow = [[self indexPathForRowAtPoint:location] retain]; - [self cellForRowAtIndexPath:_highlightedRow].highlighted = YES; - } } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - // this isn't quite how iOS seems to do it, but I think it makes sense on OSX - if (_highlightedRow) { +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if (!_highlightedRow) { UITouch *touch = [touches anyObject]; const CGPoint location = [touch locationInView:self]; - if (!CGRectContainsPoint([self rectForRowAtIndexPath:_highlightedRow], location)) { - [self cellForRowAtIndexPath:_highlightedRow].highlighted = NO; - [_highlightedRow release]; - _highlightedRow = nil; - } + _highlightedRow = [self indexPathForRowAtPoint:location]; + [self cellForRowAtIndexPath:_highlightedRow].highlighted = YES; } -} -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -{ if (_highlightedRow) { - NSIndexPath *selectedRow = [self indexPathForSelectedRow]; - - if (selectedRow) { - NSIndexPath *rowToDeselect = selectedRow; - - if (_delegateHas.willDeselectRowAtIndexPath) { - rowToDeselect = [_delegate tableView:self willDeselectRowAtIndexPath:rowToDeselect]; - } - - [self deselectRowAtIndexPath:rowToDeselect animated:NO]; - - if (_delegateHas.didDeselectRowAtIndexPath) { - [_delegate tableView:self didDeselectRowAtIndexPath:rowToDeselect]; - } - } - - NSIndexPath *rowToSelect = _highlightedRow; - - if (_delegateHas.willSelectRowAtIndexPath) { - rowToSelect = [_delegate tableView:self willSelectRowAtIndexPath:rowToSelect]; - } - [self cellForRowAtIndexPath:_highlightedRow].highlighted = NO; - [self selectRowAtIndexPath:rowToSelect animated:NO scrollPosition:UITableViewScrollPositionNone]; - - if (_delegateHas.didSelectRowAtIndexPath) { - [_delegate tableView:self didSelectRowAtIndexPath:rowToSelect]; - } - - [_highlightedRow release]; + [self _setUserSelectedRowAtIndexPath:_highlightedRow]; _highlightedRow = nil; } } @@ -791,7 +793,6 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { if (_highlightedRow) { [self cellForRowAtIndexPath:_highlightedRow].highlighted = NO; - [_highlightedRow release]; _highlightedRow = nil; } } @@ -808,7 +809,7 @@ - (void)_beginEditingRowAtIndexPath:(NSIndexPath *)indexPath self.editing = YES; if (_delegateHas.willBeginEditingRowAtIndexPath) { - [_delegate tableView:self willBeginEditingRowAtIndexPath:indexPath]; + [self.delegate tableView:self willBeginEditingRowAtIndexPath:indexPath]; } // deferring this because it presents a modal menu and that's what we do everywhere else in Chameleon @@ -822,7 +823,7 @@ - (void)_endEditingRowAtIndexPath:(NSIndexPath *)indexPath self.editing = NO; if (_delegateHas.didEndEditingRowAtIndexPath) { - [_delegate tableView:self didEndEditingRowAtIndexPath:indexPath]; + [self.delegate tableView:self didEndEditingRowAtIndexPath:indexPath]; } } } @@ -836,7 +837,7 @@ - (void)_showEditMenuForRowAtIndexPath:(NSIndexPath *)indexPath // fetch the title for the delete menu item if (_delegateHas.titleForDeleteConfirmationButtonForRowAtIndexPath) { - menuItemTitle = [_delegate tableView:self titleForDeleteConfirmationButtonForRowAtIndexPath:indexPath]; + menuItemTitle = [self.delegate tableView:self titleForDeleteConfirmationButtonForRowAtIndexPath:indexPath]; } if ([menuItemTitle length] == 0) { menuItemTitle = @"Delete"; @@ -856,12 +857,9 @@ - (void)_showEditMenuForRowAtIndexPath:(NSIndexPath *)indexPath CGPoint screenPoint = [self.window.screen convertPoint:NSPointToCGPoint(mouseLocation) fromScreen:nil]; // modally present a menu with the single delete option on it, if it was selected, then do the delete, otherwise do nothing - const BOOL didSelectItem = [menu popUpMenuPositioningItem:nil atLocation:NSPointFromCGPoint(screenPoint) inView:[self.window.screen UIKitView]]; + const BOOL didSelectItem = [menu popUpMenuPositioningItem:nil atLocation:NSPointFromCGPoint(screenPoint) inView:self.window.screen.UIKitView]; - [menu release]; - [theItem release]; - - [[UIApplication sharedApplication] _cancelTouches]; + UIApplicationInterruptTouchesInView(nil); if (didSelectItem) { [_dataSource tableView:self commitEditingStyle:UITableViewCellEditingStyleDelete forRowAtIndexPath:indexPath]; @@ -885,4 +883,71 @@ - (void)rightClick:(UITouch *)touch withEvent:(UIEvent *)event } } +// these can come down to use from AppKit if the table view somehow ends up in the responder chain. +// arrow keys move the selection, page up/down keys scroll the view + +- (void)moveUp:(id)sender +{ + NSIndexPath *selection = self.indexPathForSelectedRow; + + if (selection.row > 0) { + selection = [NSIndexPath indexPathForRow:selection.row-1 inSection:selection.section]; + } else if (selection.row == 0 && selection.section > 0) { + for (NSInteger section = selection.section - 1; section >= 0; section--) { + const NSInteger rows = [self numberOfRowsInSection:section]; + + if (rows > 0) { + selection = [NSIndexPath indexPathForRow:rows-1 inSection:section]; + break; + } + } + } + + if (![selection isEqual:self.indexPathForSelectedRow]) { + [self _setUserSelectedRowAtIndexPath:selection]; + [NSCursor setHiddenUntilMouseMoves:YES]; + } +} + +- (void)moveDown:(id)sender +{ + NSIndexPath *selection = self.indexPathForSelectedRow; + + if ((selection.row + 1) < [self numberOfRowsInSection:selection.section]) { + selection = [NSIndexPath indexPathForRow:selection.row+1 inSection:selection.section]; + } else { + for (NSInteger section = selection.section + 1; section < self.numberOfSections; section++) { + const NSInteger rows = [self numberOfRowsInSection:section]; + + if (rows > 0) { + selection = [NSIndexPath indexPathForRow:0 inSection:section]; + break; + } + } + } + + if (![selection isEqual:self.indexPathForSelectedRow]) { + [self _setUserSelectedRowAtIndexPath:selection]; + [NSCursor setHiddenUntilMouseMoves:YES]; + } +} + +- (void)pageUp:(id)sender +{ + NSArray *visibleRows = [self indexPathsForVisibleRows]; + + if ([visibleRows count] > 0) { + [self scrollToRowAtIndexPath:[visibleRows objectAtIndex:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES]; + [NSCursor setHiddenUntilMouseMoves:YES]; + [self flashScrollIndicators]; + } +} + +- (void)pageDown:(id)sender +{ + [self scrollToRowAtIndexPath:[[self indexPathsForVisibleRows] lastObject] atScrollPosition:UITableViewScrollPositionTop animated:YES]; + [NSCursor setHiddenUntilMouseMoves:YES]; + [self flashScrollIndicators]; +} + @end diff --git a/UIKit/Classes/UITableViewCell.h b/UIKit/Classes/UITableViewCell.h index 04bfb533..b962dee3 100644 --- a/UIKit/Classes/UITableViewCell.h +++ b/UIKit/Classes/UITableViewCell.h @@ -29,78 +29,56 @@ #import "UIView.h" -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) { UITableViewCellAccessoryNone, UITableViewCellAccessoryDisclosureIndicator, UITableViewCellAccessoryDetailDisclosureButton, UITableViewCellAccessoryCheckmark -} UITableViewCellAccessoryType; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewCellSeparatorStyle) { UITableViewCellSeparatorStyleNone, UITableViewCellSeparatorStyleSingleLine, UITableViewCellSeparatorStyleSingleLineEtched -} UITableViewCellSeparatorStyle; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2, UITableViewCellStyleSubtitle -} UITableViewCellStyle; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewCellSelectionStyle) { UITableViewCellSelectionStyleNone, UITableViewCellSelectionStyleBlue, UITableViewCellSelectionStyleGray -} UITableViewCellSelectionStyle; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITableViewCellEditingStyle) { UITableViewCellEditingStyleNone, UITableViewCellEditingStyleDelete, UITableViewCellEditingStyleInsert -} UITableViewCellEditingStyle; +}; -@class UITableViewCellSeparator, UILabel, UIImageView; - -@interface UITableViewCell : UIView { -@private - UITableViewCellStyle _style; - UITableViewCellSeparator *_seperatorView; - UIView *_contentView; - UILabel *_textLabel; - UILabel *_detailTextLabel; // not yet displayed! - UIImageView *_imageView; - UIView *_backgroundView; - UIView *_selectedBackgroundView; - UITableViewCellAccessoryType _accessoryType; - UIView *_accessoryView; - UITableViewCellAccessoryType _editingAccessoryType; - UITableViewCellSelectionStyle _selectionStyle; - NSInteger _indentationLevel; - BOOL _editing; - BOOL _selected; - BOOL _highlighted; - BOOL _showingDeleteConfirmation; - NSString *_reuseIdentifier; - CGFloat _indentationWidth; -} +@class UILabel, UIImageView; +@interface UITableViewCell : UIView - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier; - (void)setSelected:(BOOL)selected animated:(BOOL)animated; - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated; - (void)prepareForReuse; -@property (nonatomic, readonly, retain) UIView *contentView; -@property (nonatomic, readonly, retain) UILabel *textLabel; -@property (nonatomic, readonly, retain) UILabel *detailTextLabel; -@property (nonatomic, readonly, retain) UIImageView *imageView; -@property (nonatomic, retain) UIView *backgroundView; -@property (nonatomic, retain) UIView *selectedBackgroundView; +@property (nonatomic, readonly, strong) UIView *contentView; +@property (nonatomic, readonly, strong) UILabel *textLabel; +@property (nonatomic, readonly, strong) UILabel *detailTextLabel; +@property (nonatomic, readonly, strong) UIImageView *imageView; +@property (nonatomic, strong) UIView *backgroundView; +@property (nonatomic, strong) UIView *selectedBackgroundView; @property (nonatomic) UITableViewCellSelectionStyle selectionStyle; @property (nonatomic) NSInteger indentationLevel; @property (nonatomic) UITableViewCellAccessoryType accessoryType; -@property (nonatomic, retain) UIView *accessoryView; +@property (nonatomic, strong) UIView *accessoryView; @property (nonatomic) UITableViewCellAccessoryType editingAccessoryType; @property (nonatomic, getter=isSelected) BOOL selected; @property (nonatomic, getter=isHighlighted) BOOL highlighted; @@ -108,5 +86,4 @@ typedef enum { @property (nonatomic, readonly) BOOL showingDeleteConfirmation; // not yet implemented @property (nonatomic, readonly, copy) NSString *reuseIdentifier; @property (nonatomic, assign) CGFloat indentationWidth; // 10 per default - @end diff --git a/UIKit/Classes/UITableViewCell.m b/UIKit/Classes/UITableViewCell.m index d3f5a429..865538c3 100644 --- a/UIKit/Classes/UITableViewCell.m +++ b/UIKit/Classes/UITableViewCell.m @@ -36,12 +36,13 @@ extern CGFloat _UITableViewDefaultRowHeight; -@implementation UITableViewCell -@synthesize accessoryType=_accessoryType, selectionStyle=_selectionStyle, indentationLevel=_indentationLevel; -@synthesize editingAccessoryType=_editingAccessoryType, selected=_selected, backgroundView=_backgroundView; -@synthesize selectedBackgroundView=_selectedBackgroundView, highlighted=_highlighted, reuseIdentifier=_reuseIdentifier; -@synthesize editing = _editing, detailTextLabel = _detailTextLabel, showingDeleteConfirmation = _showingDeleteConfirmation; -@synthesize indentationWidth=_indentationWidth, accessoryView=_accessoryView; +@implementation UITableViewCell { + UITableViewCellStyle _style; + UITableViewCellSeparator *_seperatorView; + UIView *_contentView; + UIImageView *_imageView; + UILabel *_textLabel; +} - (id)initWithFrame:(CGRect)frame { @@ -68,19 +69,6 @@ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reus return self; } -- (void)dealloc -{ - [_seperatorView release]; - [_contentView release]; - [_accessoryView release]; - [_textLabel release]; - [_detailTextLabel release]; - [_imageView release]; - [_backgroundView release]; - [_selectedBackgroundView release]; - [_reuseIdentifier release]; - [super dealloc]; -} - (void)layoutSubviews { @@ -220,8 +208,7 @@ - (void)setBackgroundView:(UIView *)theBackgroundView { if (theBackgroundView != _backgroundView) { [_backgroundView removeFromSuperview]; - [_backgroundView release]; - _backgroundView = [theBackgroundView retain]; + _backgroundView = theBackgroundView; [self addSubview:_backgroundView]; self.backgroundColor = [UIColor clearColor]; } @@ -231,8 +218,7 @@ - (void)setSelectedBackgroundView:(UIView *)theSelectedBackgroundView { if (theSelectedBackgroundView != _selectedBackgroundView) { [_selectedBackgroundView removeFromSuperview]; - [_selectedBackgroundView release]; - _selectedBackgroundView = [theSelectedBackgroundView retain]; + _selectedBackgroundView = theSelectedBackgroundView; _selectedBackgroundView.hidden = !_selected; [self addSubview:_selectedBackgroundView]; } diff --git a/UIKit/Classes/UITableViewCellSeparator.h b/UIKit/Classes/UITableViewCellSeparator.h index b58cfb9b..361a2728 100644 --- a/UIKit/Classes/UITableViewCellSeparator.h +++ b/UIKit/Classes/UITableViewCellSeparator.h @@ -32,11 +32,7 @@ @class UIColor; -@interface UITableViewCellSeparator : UIView { -@private - UITableViewCellSeparatorStyle _style; - UIColor *_color; -} +@interface UITableViewCellSeparator : UIView - (void)setSeparatorStyle:(UITableViewCellSeparatorStyle)theStyle color:(UIColor *)theColor; diff --git a/UIKit/Classes/UITableViewCellSeparator.m b/UIKit/Classes/UITableViewCellSeparator.m index cb2b0a7d..53630fe1 100644 --- a/UIKit/Classes/UITableViewCellSeparator.m +++ b/UIKit/Classes/UITableViewCellSeparator.m @@ -31,7 +31,10 @@ #import "UIColor.h" #import "UIGraphics.h" -@implementation UITableViewCellSeparator +@implementation UITableViewCellSeparator { + UITableViewCellSeparatorStyle _style; + UIColor *_color; +} - (id)initWithFrame:(CGRect)frame { @@ -42,11 +45,6 @@ - (id)initWithFrame:(CGRect)frame return self; } -- (void)dealloc -{ - [_color release]; - [super dealloc]; -} - (void)setSeparatorStyle:(UITableViewCellSeparatorStyle)theStyle color:(UIColor *)theColor { @@ -56,8 +54,7 @@ - (void)setSeparatorStyle:(UITableViewCellSeparatorStyle)theStyle color:(UIColor } if (_color != theColor) { - [_color release]; - _color = [theColor retain]; + _color = theColor; [self setNeedsDisplay]; } diff --git a/UIKit/Classes/UITableViewController.h b/UIKit/Classes/UITableViewController.h index e30b9dc8..40b618e0 100644 --- a/UIKit/Classes/UITableViewController.h +++ b/UIKit/Classes/UITableViewController.h @@ -30,16 +30,9 @@ #import "UIViewController.h" #import "UITableView.h" -@interface UITableViewController : UIViewController { -@private - UITableViewStyle _style; - BOOL _clearsSelectionOnViewWillAppear; - BOOL _hasReloaded; -} - +@interface UITableViewController : UIViewController - (id)initWithStyle:(UITableViewStyle)style; -@property (nonatomic, retain) UITableView *tableView; +@property (nonatomic, strong) UITableView *tableView; @property (nonatomic) BOOL clearsSelectionOnViewWillAppear; - @end diff --git a/UIKit/Classes/UITableViewController.m b/UIKit/Classes/UITableViewController.m index 82d91fcb..c2e80410 100644 --- a/UIKit/Classes/UITableViewController.m +++ b/UIKit/Classes/UITableViewController.m @@ -29,8 +29,10 @@ #import "UITableViewController.h" -@implementation UITableViewController -@synthesize clearsSelectionOnViewWillAppear=_clearsSelectionOnViewWillAppear; +@implementation UITableViewController { + UITableViewStyle _style; + BOOL _hasReloaded; +} - (id)init { @@ -47,7 +49,7 @@ - (id)initWithStyle:(UITableViewStyle)theStyle - (void)loadView { - self.tableView = [[[UITableView alloc] initWithFrame:CGRectMake(0,0,320,480) style:_style] autorelease]; + self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0,0,320,480) style:_style]; self.tableView.delegate = self; self.tableView.dataSource = self; } diff --git a/UIKit/Classes/UITableViewSection.h b/UIKit/Classes/UITableViewSection.h index 42686d45..c3e05355 100644 --- a/UIKit/Classes/UITableViewSection.h +++ b/UIKit/Classes/UITableViewSection.h @@ -31,17 +31,7 @@ @class UIView; -@interface UITableViewSection : NSObject { - CGFloat rowsHeight; - CGFloat headerHeight; - CGFloat footerHeight; - NSInteger numberOfRows; - CGFloat *rowHeights; - UIView *headerView; - UIView *footerView; - NSString *headerTitle; - NSString *footerTitle; -} +@interface UITableViewSection : NSObject - (CGFloat)sectionHeight; @@ -52,8 +42,8 @@ @property (nonatomic, assign) CGFloat footerHeight; @property (nonatomic, readonly) NSInteger numberOfRows; @property (nonatomic, readonly) CGFloat *rowHeights; -@property (nonatomic, retain) UIView *headerView; -@property (nonatomic, retain) UIView *footerView; +@property (nonatomic, strong) UIView *headerView; +@property (nonatomic, strong) UIView *footerView; @property (nonatomic, copy) NSString *headerTitle; @property (nonatomic, copy) NSString *footerTitle; diff --git a/UIKit/Classes/UITableViewSection.m b/UIKit/Classes/UITableViewSection.m index 51c6b522..d58beea4 100644 --- a/UIKit/Classes/UITableViewSection.m +++ b/UIKit/Classes/UITableViewSection.m @@ -31,27 +31,21 @@ #import "UIView.h" @implementation UITableViewSection -@synthesize rowsHeight, headerHeight, footerHeight, rowHeights, numberOfRows, headerView, footerView, headerTitle, footerTitle; - (CGFloat)sectionHeight { - return rowsHeight + headerHeight + footerHeight; + return self.rowsHeight + self.headerHeight + self.footerHeight; } - (void)setNumberOfRows:(NSInteger)rows withHeights:(CGFloat *)newRowHeights { - rowHeights = realloc(rowHeights, sizeof(CGFloat) * rows); - memcpy(rowHeights, newRowHeights, sizeof(CGFloat) * rows); - numberOfRows = rows; + _rowHeights = realloc(_rowHeights, sizeof(CGFloat) * rows); + memcpy(_rowHeights, newRowHeights, sizeof(CGFloat) * rows); + _numberOfRows = rows; } - (void)dealloc { - if (rowHeights) free(rowHeights); - [headerView release]; - [footerView release]; - [headerTitle release]; - [footerTitle release]; - [super dealloc]; + if (_rowHeights) free(_rowHeights); } @end diff --git a/UIKit/Classes/UITableViewSectionLabel.m b/UIKit/Classes/UITableViewSectionLabel.m index b09d7333..1eb4d0ce 100644 --- a/UIKit/Classes/UITableViewSectionLabel.m +++ b/UIKit/Classes/UITableViewSectionLabel.m @@ -40,7 +40,7 @@ + (UITableViewSectionLabel *)sectionLabelWithTitle:(NSString *)title label.textColor = [UIColor whiteColor]; label.shadowColor = [UIColor colorWithRed:100/255.f green:105/255.f blue:110/255.f alpha:1]; label.shadowOffset = CGSizeMake(0,1); - return [label autorelease]; + return label; } - (void)drawRect:(CGRect)rect diff --git a/UIKit/Classes/UITapGestureRecognizer.h b/UIKit/Classes/UITapGestureRecognizer.h index f6bbcc94..ba88aae5 100644 --- a/UIKit/Classes/UITapGestureRecognizer.h +++ b/UIKit/Classes/UITapGestureRecognizer.h @@ -29,12 +29,7 @@ #import "UIGestureRecognizer.h" -@interface UITapGestureRecognizer : UIGestureRecognizer { - NSUInteger _numberOfTapsRequired; - NSUInteger _numberOfTouchesRequired; -} - +@interface UITapGestureRecognizer : UIGestureRecognizer @property (nonatomic) NSUInteger numberOfTapsRequired; @property (nonatomic) NSUInteger numberOfTouchesRequired; - @end diff --git a/UIKit/Classes/UITapGestureRecognizer.m b/UIKit/Classes/UITapGestureRecognizer.m index dfa512eb..05a98bcb 100644 --- a/UIKit/Classes/UITapGestureRecognizer.m +++ b/UIKit/Classes/UITapGestureRecognizer.m @@ -32,7 +32,6 @@ #import "UITouch.h" @implementation UITapGestureRecognizer -@synthesize numberOfTapsRequired=_numberOfTapsRequired, numberOfTouchesRequired=_numberOfTouchesRequired; - (id)initWithTarget:(id)target action:(SEL)action { diff --git a/UIKit/Classes/UITextField.h b/UIKit/Classes/UITextField.h index 9c569090..23f28bc9 100644 --- a/UIKit/Classes/UITextField.h +++ b/UIKit/Classes/UITextField.h @@ -29,27 +29,27 @@ #import "UIControl.h" #import "UIStringDrawing.h" -#import "UITextInputTraits.h" +#import "UITextInput.h" extern NSString *const UITextFieldTextDidBeginEditingNotification; extern NSString *const UITextFieldTextDidChangeNotification; extern NSString *const UITextFieldTextDidEndEditingNotification; -typedef enum { +typedef NS_ENUM(NSInteger, UITextBorderStyle) { UITextBorderStyleNone, UITextBorderStyleLine, UITextBorderStyleBezel, UITextBorderStyleRoundedRect -} UITextBorderStyle; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITextFieldViewMode) { UITextFieldViewModeNever, UITextFieldViewModeWhileEditing, UITextFieldViewModeUnlessEditing, UITextFieldViewModeAlways -} UITextFieldViewMode; +}; -@class UIFont, UIColor, UITextField, UIImage, UITextLayer; +@class UIFont, UIColor, UITextField, UIImage; @protocol UITextFieldDelegate @optional @@ -63,39 +63,7 @@ typedef enum { - (BOOL)textFieldShouldReturn:(UITextField *)textField; @end -@interface UITextField : UIControl { -@private - UITextLayer *_textLayer; - - __unsafe_unretained id _delegate; - UITextFieldViewMode _clearButtonMode; - UIView *_leftView; - UITextFieldViewMode _leftViewMode; - UIView *_rightView; - UITextFieldViewMode _rightViewMode; - UIImage *_background; - UIImage *_disabledBackground; - BOOL _editing; - BOOL _clearsOnBeginEditing; - BOOL _adjustsFontSizeToFitWidth; - NSString *_placeholder; - UITextBorderStyle _borderStyle; - CGFloat _minimumFontSize; - - UIView *_inputAccessoryView; - UIView *_inputView; - - struct { - unsigned shouldBeginEditing : 1; - unsigned didBeginEditing : 1; - unsigned shouldEndEditing : 1; - unsigned didEndEditing : 1; - unsigned shouldChangeCharacters : 1; - unsigned shouldClear : 1; - unsigned shouldReturn : 1; - } _delegateHas; -} - +@interface UITextField : UIControl - (CGRect)borderRectForBounds:(CGRect)bounds; - (CGRect)clearButtonRectForBounds:(CGRect)bounds; - (CGRect)editingRectForBounds:(CGRect)bounds; @@ -111,24 +79,33 @@ typedef enum { @property (nonatomic, assign) UITextAlignment textAlignment; @property (nonatomic, copy) NSString *placeholder; @property (nonatomic, copy) NSString *text; -@property (nonatomic, retain) UIFont *font; +@property (nonatomic, strong) UIFont *font; @property (nonatomic) UITextBorderStyle borderStyle; -@property (nonatomic, retain) UIColor *textColor; +@property (nonatomic, strong) UIColor *textColor; @property (nonatomic, readonly, getter=isEditing) BOOL editing; @property (nonatomic) BOOL clearsOnBeginEditing; @property (nonatomic) BOOL adjustsFontSizeToFitWidth; @property (nonatomic) CGFloat minimumFontSize; -@property (nonatomic, retain) UIImage *background; -@property (nonatomic, retain) UIImage *disabledBackground; +@property (nonatomic, strong) UIImage *background; +@property (nonatomic, strong) UIImage *disabledBackground; @property (nonatomic) UITextFieldViewMode clearButtonMode; -@property (nonatomic, retain) UIView *leftView; +@property (nonatomic, strong) UIView *leftView; @property (nonatomic) UITextFieldViewMode leftViewMode; -@property (nonatomic, retain) UIView *rightView; +@property (nonatomic, strong) UIView *rightView; @property (nonatomic) UITextFieldViewMode rightViewMode; -@property (nonatomic, readwrite, retain) UIView *inputAccessoryView; -@property (nonatomic, readwrite, retain) UIView *inputView; +@property (readwrite, strong) UIView *inputAccessoryView; +@property (readwrite, strong) UIView *inputView; +@end + +// for unknown reasons, Apple's UIKit actually declares this here (and not in UIView) +// the documentation makes it sound as if this only resigns text fields, but the comment +// in UIKit's actual UITextField header file indicates it may only care about first +// responder status, so that is how I will implement it +@interface UIView (UITextField) +- (BOOL)endEditing:(BOOL)force; @end + diff --git a/UIKit/Classes/UITextField.m b/UIKit/Classes/UITextField.m index 27f24fed..446fc31b 100644 --- a/UIKit/Classes/UITextField.m +++ b/UIKit/Classes/UITextField.m @@ -44,11 +44,20 @@ @interface UIControl () @interface UITextField () @end -@implementation UITextField -@synthesize delegate=_delegate, background=_background, disabledBackground=_disabledBackground, editing=_editing, clearsOnBeginEditing=_clearsOnBeginEditing; -@synthesize adjustsFontSizeToFitWidth=_adjustsFontSizeToFitWidth, clearButtonMode=_clearButtonMode, leftView=_leftView, rightView=_rightView; -@synthesize leftViewMode=_leftViewMode, rightViewMode=_rightViewMode, placeholder=_placeholder, borderStyle=_borderStyle; -@synthesize inputAccessoryView=_inputAccessoryView, inputView=_inputView, minimumFontSize=_minimumFontSize; +@implementation UITextField { + UITextLayer *_textLayer; + + struct { + unsigned shouldBeginEditing : 1; + unsigned didBeginEditing : 1; + unsigned shouldEndEditing : 1; + unsigned didEndEditing : 1; + unsigned shouldChangeCharacters : 1; + unsigned shouldClear : 1; + unsigned shouldReturn : 1; + } _delegateHas; +} +@synthesize inputAccessoryView, inputView; - (id)initWithFrame:(CGRect)frame { @@ -71,15 +80,6 @@ - (id)initWithFrame:(CGRect)frame - (void)dealloc { [_textLayer removeFromSuperlayer]; - [_textLayer release]; - [_leftView release]; - [_rightView release]; - [_background release]; - [_disabledBackground release]; - [_placeholder release]; - [_inputAccessoryView release]; - [_inputView release]; - [super dealloc]; } - (BOOL)_isLeftViewVisible @@ -134,7 +134,6 @@ - (void)setDelegate:(id)theDelegate - (void)setPlaceholder:(NSString *)thePlaceholder { if (![thePlaceholder isEqualToString:_placeholder]) { - [_placeholder release]; _placeholder = [thePlaceholder copy]; [self setNeedsDisplay]; } @@ -151,8 +150,7 @@ - (void)setBorderStyle:(UITextBorderStyle)style - (void)setBackground:(UIImage *)aBackground { if (aBackground != _background) { - [_background release]; - _background = [aBackground retain]; + _background = aBackground; [self setNeedsDisplay]; } } @@ -160,8 +158,7 @@ - (void)setBackground:(UIImage *)aBackground - (void)setDisabledBackground:(UIImage *)aBackground { if (aBackground != _disabledBackground) { - [_disabledBackground release]; - _disabledBackground = [aBackground retain]; + _disabledBackground = aBackground; [self setNeedsDisplay]; } } @@ -170,8 +167,7 @@ - (void)setLeftView:(UIView *)leftView { if (leftView != _leftView) { [_leftView removeFromSuperview]; - [_leftView release]; - _leftView = [leftView retain]; + _leftView = leftView; [self addSubview:_leftView]; } } @@ -180,8 +176,7 @@ - (void)setRightView:(UIView *)rightView { if (rightView != _rightView) { [_rightView removeFromSuperview]; - [_rightView release]; - _rightView = [rightView retain]; + _rightView = rightView; [self addSubview:_rightView]; } } @@ -372,11 +367,13 @@ - (BOOL)canBecomeFirstResponder - (BOOL)becomeFirstResponder { - if ([super becomeFirstResponder]) { - return [_textLayer becomeFirstResponder]; - } else { - return NO; + BOOL result = [super becomeFirstResponder]; + + if (result && (result = [_textLayer becomeFirstResponder])) { + [self _textDidBeginEditing]; } + + return result; } - (BOOL)resignFirstResponder @@ -514,4 +511,67 @@ - (id)mouseCursorForEvent:(UIEvent *)event return [NSCursor IBeamCursor]; } +- (CGSize)sizeThatFits:(CGSize)size +{ + return [_textLayer sizeThatFits:size]; +} + +#pragma mark UITextInput + +- (void)setSelectedTextRange:(UITextRange *)range +{ +} + +- (UITextRange *)selectedTextRange +{ + return nil; +} + +- (UITextRange *)beginningOfDocument +{ + return nil; +} + +- (UITextPosition *)endOfDocument +{ + return nil; +} + +- (NSInteger)offsetFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition +{ + return 0; +} + +- (UITextPosition *)positionFromPosition:(UITextPosition *)position offset:(NSInteger)offset +{ + return nil; +} + +- (UITextRange *)textRangeFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition +{ + return nil; +} + +@end + + +@implementation UIView (UITextField) + +- (BOOL)endEditing:(BOOL)force +{ + if ([self isFirstResponder]) { + if (force || [self canResignFirstResponder]) { + return [self resignFirstResponder]; + } + } else { + for (UIView *view in self.subviews) { + if ([view endEditing:force]) { + return YES; + } + } + } + + return NO; +} + @end diff --git a/UIKit/Classes/UIViewBlockAnimationDelegate.m b/UIKit/Classes/UITextInput.h similarity index 62% rename from UIKit/Classes/UIViewBlockAnimationDelegate.m rename to UIKit/Classes/UITextInput.h index 8ad5d1f1..07dd4216 100644 --- a/UIKit/Classes/UIViewBlockAnimationDelegate.m +++ b/UIKit/Classes/UITextInput.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -27,27 +27,25 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIViewBlockAnimationDelegate.h" -#import "UIApplication.h" +#import "UITextInputTraits.h" -@implementation UIViewBlockAnimationDelegate -@synthesize completion=_completion, ignoreInteractionEvents=_ignoreInteractionEvents; +@interface UITextPosition : NSObject +@end -- (void)dealloc -{ - [_completion release]; - [super dealloc]; -} +@interface UITextRange : NSObject +@property (nonatomic, readonly) UITextPosition *start; +@property (nonatomic, readonly) UITextPosition *end; +@property (nonatomic, readonly, getter=isEmpty) BOOL empty; +@end -- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished -{ - if (_completion) { - _completion([finished boolValue]); - } - - if (_ignoreInteractionEvents) { - [[UIApplication sharedApplication] endIgnoringInteractionEvents]; - } -} +@protocol UIKeyInput +@end +@protocol UITextInput +@property (readwrite, copy) UITextRange *selectedTextRange; +@property (nonatomic, readonly) UITextPosition *beginningOfDocument; +@property (nonatomic, readonly) UITextPosition *endOfDocument; +- (NSInteger)offsetFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition; +- (UITextPosition *)positionFromPosition:(UITextPosition *)position offset:(NSInteger)offset; +- (UITextRange *)textRangeFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition; @end diff --git a/UIKit/Classes/UIKey+UIPrivate.h b/UIKit/Classes/UITextInput.m similarity index 90% rename from UIKit/Classes/UIKey+UIPrivate.h rename to UIKit/Classes/UITextInput.m index 31795af3..dc51db4a 100644 --- a/UIKit/Classes/UIKey+UIPrivate.h +++ b/UIKit/Classes/UITextInput.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -27,10 +27,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIKey.h" +#import "UITextInput.h" -@class NSEvent; +@implementation UITextPosition +@end -@interface UIKey (UIPrivate) -- (id)initWithNSEvent:(NSEvent *)event; +@implementation UITextRange @end diff --git a/UIKit/Classes/UITextInputTraits.h b/UIKit/Classes/UITextInputTraits.h index 1c3ca1bc..32872f17 100644 --- a/UIKit/Classes/UITextInputTraits.h +++ b/UIKit/Classes/UITextInputTraits.h @@ -29,25 +29,25 @@ #import -typedef enum { +typedef NS_ENUM(NSInteger, UITextAutocapitalizationType) { UITextAutocapitalizationTypeNone, UITextAutocapitalizationTypeWords, UITextAutocapitalizationTypeSentences, UITextAutocapitalizationTypeAllCharacters, -} UITextAutocapitalizationType; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITextAutocorrectionType) { UITextAutocorrectionTypeDefault, UITextAutocorrectionTypeNo, UITextAutocorrectionTypeYes, -} UITextAutocorrectionType; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIKeyboardAppearance) { UIKeyboardAppearanceDefault, UIKeyboardAppearanceAlert, -} UIKeyboardAppearance; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIKeyboardType) { UIKeyboardTypeDefault, UIKeyboardTypeASCIICapable, UIKeyboardTypeNumbersAndPunctuation, @@ -56,10 +56,12 @@ typedef enum { UIKeyboardTypePhonePad, UIKeyboardTypeNamePhonePad, UIKeyboardTypeEmailAddress, + UIKeyboardTypeDecimalPad, + UIKeyboardTypeTwitter, UIKeyboardTypeAlphabet = UIKeyboardTypeASCIICapable -} UIKeyboardType; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIReturnKeyType) { UIReturnKeyDefault, UIReturnKeyGo, UIReturnKeyGoogle, @@ -71,7 +73,7 @@ typedef enum { UIReturnKeyYahoo, UIReturnKeyDone, UIReturnKeyEmergencyCall, -} UIReturnKeyType; +}; @protocol UITextInputTraits @property (nonatomic) UITextAutocapitalizationType autocapitalizationType; diff --git a/UIKit/Classes/UITextLayer.h b/UIKit/Classes/UITextLayer.h index c6092e0f..9cd1ed01 100644 --- a/UIKit/Classes/UITextLayer.h +++ b/UIKit/Classes/UITextLayer.h @@ -54,7 +54,6 @@ @protocol UITextLayerTextDelegate @required - (BOOL)_textShouldBeginEditing; -- (void)_textDidBeginEditing; - (BOOL)_textShouldEndEditing; - (void)_textDidEndEditing; - (BOOL)_textShouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; @@ -65,34 +64,19 @@ - (void)_textDidReceiveReturnKey; @end -@interface UITextLayer : CALayer { - id containerView; - BOOL containerCanScroll; - UICustomNSTextView *textView; - UICustomNSClipView *clipView; - BOOL secureTextEntry; - BOOL editable; - UIColor *textColor; - UIFont *font; - BOOL changingResponderStatus; - - struct { - unsigned didChange : 1; - unsigned didChangeSelection : 1; - unsigned didReturnKey : 1; - } textDelegateHas; -} +@interface UITextLayer : CALayer - (id)initWithContainer:(UIView *)aView isField:(BOOL)isField; - (void)setContentOffset:(CGPoint)contentOffset; - (void)scrollRangeToVisible:(NSRange)range; - (BOOL)becomeFirstResponder; - (BOOL)resignFirstResponder; +- (CGSize)sizeThatFits:(CGSize)size; @property (nonatomic, assign) NSRange selectedRange; @property (nonatomic, copy) NSString *text; -@property (nonatomic, retain) UIColor *textColor; -@property (nonatomic, retain) UIFont *font; +@property (nonatomic, strong) UIColor *textColor; +@property (nonatomic, strong) UIFont *font; @property (nonatomic, assign) BOOL editable; @property (nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; @property (nonatomic, assign) UITextAlignment textAlignment; diff --git a/UIKit/Classes/UITextLayer.m b/UIKit/Classes/UITextLayer.m index 638e48ab..555ba2ee 100644 --- a/UIKit/Classes/UITextLayer.m +++ b/UIKit/Classes/UITextLayer.m @@ -32,12 +32,10 @@ #import "UICustomNSTextView.h" #import "UICustomNSClipView.h" #import "UIWindow.h" -#import "UIScreen+UIPrivate.h" -#import "UIScreenAppKitIntegration.h" -#import "UIApplication+UIPrivate.h" +#import "UIKitView.h" #import "AppKitIntegration.h" #import "UIView+UIPrivate.h" -#import "UIKitView.h" +#import "UIKey.h" #import #import @@ -45,31 +43,42 @@ @interface UITextLayer () *_containerView; + BOOL _containerCanScroll; + UICustomNSTextView *_textView; + UICustomNSClipView *_clipView; + BOOL _changingResponderStatus; + + struct { + unsigned didChange : 1; + unsigned didChangeSelection : 1; + unsigned didReturnKey : 1; + } _textDelegateHas; +} - (id)initWithContainer:(UIView *)aView isField:(BOOL)isField { if ((self=[super init])) { self.masksToBounds = NO; - containerView = aView; + _containerView = aView; - textDelegateHas.didChange = [containerView respondsToSelector:@selector(_textDidChange)]; - textDelegateHas.didChangeSelection = [containerView respondsToSelector:@selector(_textDidChangeSelection)]; - textDelegateHas.didReturnKey = [containerView respondsToSelector:@selector(_textDidReceiveReturnKey)]; + _textDelegateHas.didChange = [_containerView respondsToSelector:@selector(_textDidChange)]; + _textDelegateHas.didChangeSelection = [_containerView respondsToSelector:@selector(_textDidChangeSelection)]; + _textDelegateHas.didReturnKey = [_containerView respondsToSelector:@selector(_textDidReceiveReturnKey)]; - containerCanScroll = [containerView respondsToSelector:@selector(setContentOffset:)] - && [containerView respondsToSelector:@selector(contentOffset)] - && [containerView respondsToSelector:@selector(setContentSize:)] - && [containerView respondsToSelector:@selector(contentSize)] - && [containerView respondsToSelector:@selector(isScrollEnabled)]; + _containerCanScroll = [_containerView respondsToSelector:@selector(setContentOffset:)] + && [_containerView respondsToSelector:@selector(contentOffset)] + && [_containerView respondsToSelector:@selector(setContentSize:)] + && [_containerView respondsToSelector:@selector(contentSize)] + && [_containerView respondsToSelector:@selector(isScrollEnabled)]; - clipView = [(UICustomNSClipView *)[UICustomNSClipView alloc] initWithFrame:NSMakeRect(0,0,100,100)]; - textView = [(UICustomNSTextView *)[UICustomNSTextView alloc] initWithFrame:[clipView frame] secureTextEntry:secureTextEntry isField:isField]; + _clipView = [(UICustomNSClipView *)[UICustomNSClipView alloc] initWithFrame:NSMakeRect(0,0,100,100)]; + _textView = [(UICustomNSTextView *)[UICustomNSTextView alloc] initWithFrame:[_clipView frame] secureTextEntry:_secureTextEntry isField:isField]; - [textView setDelegate:self]; - [clipView setDocumentView:textView]; + [_textView setDelegate:self]; + [_clipView setDocumentView:_textView]; self.textAlignment = UITextAlignmentLeft; [self setNeedsLayout]; @@ -79,13 +88,8 @@ - (id)initWithContainer:(UIView @optional @@ -49,40 +49,18 @@ extern NSString *const UITextViewTextDidEndEditingNotification; - (void)textViewDidChangeSelection:(UITextView *)textView; @end -@interface UITextView : UIScrollView { -@private - UITextLayer *_textLayer; - UIDataDetectorTypes _dataDetectorTypes; - - UIView *_inputAccessoryView; - UIView *_inputView; - - struct { - unsigned shouldBeginEditing : 1; - unsigned didBeginEditing : 1; - unsigned shouldEndEditing : 1; - unsigned didEndEditing : 1; - unsigned shouldChangeText : 1; - unsigned didChange : 1; - unsigned didChangeSelection : 1; - } _delegateHas; -} - +@interface UITextView : UIScrollView - (void)scrollRangeToVisible:(NSRange)range; - +- (BOOL)hasText; @property (nonatomic) UITextAlignment textAlignment; // stub, not yet implemented! @property (nonatomic) NSRange selectedRange; @property (nonatomic, getter=isEditable) BOOL editable; @property (nonatomic, copy) NSString *text; -@property (nonatomic, retain) UIColor *textColor; -@property (nonatomic, retain) UIFont *font; +@property (nonatomic, strong) UIColor *textColor; +@property (nonatomic, strong) UIFont *font; @property (nonatomic) UIDataDetectorTypes dataDetectorTypes; @property (nonatomic, assign) id delegate; - -@property (nonatomic, readwrite, retain) UIView *inputAccessoryView; -@property (nonatomic, readwrite, retain) UIView *inputView; - -- (BOOL)hasText; - +@property (readwrite, strong) UIView *inputAccessoryView; +@property (readwrite, strong) UIView *inputView; @end diff --git a/UIKit/Classes/UITextView.m b/UIKit/Classes/UITextView.m index a89563df..9c5106fd 100644 --- a/UIKit/Classes/UITextView.m +++ b/UIKit/Classes/UITextView.m @@ -45,9 +45,20 @@ @interface UITextView () @end -@implementation UITextView -@synthesize dataDetectorTypes=_dataDetectorTypes, inputAccessoryView=_inputAccessoryView, inputView=_inputView; -@dynamic delegate; +@implementation UITextView { + UITextLayer *_textLayer; + + struct { + unsigned shouldBeginEditing : 1; + unsigned didBeginEditing : 1; + unsigned shouldEndEditing : 1; + unsigned didEndEditing : 1; + unsigned shouldChangeText : 1; + unsigned didChange : 1; + unsigned didChangeSelection : 1; + } _delegateHas; +} +@synthesize inputAccessoryView, inputView; - (id)initWithFrame:(CGRect)frame { @@ -68,10 +79,6 @@ - (id)initWithFrame:(CGRect)frame - (void)dealloc { [_textLayer removeFromSuperlayer]; - [_textLayer release]; - [_inputAccessoryView release]; - [_inputView release]; - [super dealloc]; } - (void)layoutSubviews @@ -328,4 +335,45 @@ - (id)mouseCursorForEvent:(UIEvent *)event return self.editable? [NSCursor IBeamCursor] : nil; } +- (CGSize)sizeThatFits:(CGSize)size +{ + return [_textLayer sizeThatFits:size]; +} + +#pragma mark UITextInput + +- (void)setSelectedTextRange:(UITextRange *)range +{ +} + +- (UITextRange *)selectedTextRange +{ + return nil; +} + +- (UITextRange *)beginningOfDocument +{ + return nil; +} + +- (UITextPosition *)endOfDocument +{ + return nil; +} + +- (NSInteger)offsetFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition +{ + return 0; +} + +- (UITextPosition *)positionFromPosition:(UITextPosition *)position offset:(NSInteger)offset +{ + return nil; +} + +- (UITextRange *)textRangeFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition +{ + return nil; +} + @end diff --git a/UIKit/Classes/UIThreePartImage.h b/UIKit/Classes/UIThreePartImage.h index 1390109b..a0959ca8 100644 --- a/UIKit/Classes/UIThreePartImage.h +++ b/UIKit/Classes/UIThreePartImage.h @@ -29,11 +29,7 @@ #import "UIImage+UIPrivate.h" -@interface UIThreePartImage : UIImage { -@private - NSInteger _capSize; - BOOL _vertical; -} +@interface UIThreePartImage : UIImage - (id)initWithRepresentations:(NSArray *)reps capSize:(NSInteger)capSize vertical:(BOOL)isVertical; diff --git a/UIKit/Classes/UIThreePartImage.m b/UIKit/Classes/UIThreePartImage.m index 5ff5ffe9..31834ad0 100644 --- a/UIKit/Classes/UIThreePartImage.m +++ b/UIKit/Classes/UIThreePartImage.m @@ -30,7 +30,10 @@ #import "UIThreePartImage.h" #import "UIImageRep.h" -@implementation UIThreePartImage +@implementation UIThreePartImage { + NSInteger _capSize; + BOOL _vertical; +} - (id)initWithRepresentations:(NSArray *)reps capSize:(NSInteger)capSize vertical:(BOOL)isVertical { diff --git a/UIKit/Classes/UIToolbar.h b/UIKit/Classes/UIToolbar.h index 54ced7b0..a1f80505 100644 --- a/UIKit/Classes/UIToolbar.h +++ b/UIKit/Classes/UIToolbar.h @@ -30,25 +30,20 @@ #import "UIView.h" #import "UIInterface.h" -typedef enum { +typedef NS_ENUM(NSInteger, UIToolbarPosition) { UIToolbarPositionAny = 0, UIToolbarPositionBottom = 1, UIToolbarPositionTop = 2, -} UIToolbarPosition; - -@interface UIToolbar : UIView { -@private - UIBarStyle _barStyle; - UIColor *_tintColor; - NSMutableArray *_toolbarItems; - BOOL _translucent; -} +}; +@interface UIToolbar : UIView - (void)setItems:(NSArray *)items animated:(BOOL)animated; +- (UIImage *)backgroundImageForToolbarPosition:(UIToolbarPosition)topOrBottom barMetrics:(UIBarMetrics)barMetrics; +- (void)setBackgroundImage:(UIImage *)backgroundImage forToolbarPosition:(UIToolbarPosition)topOrBottom barMetrics:(UIBarMetrics)barMetrics; + @property (nonatomic) UIBarStyle barStyle; -@property (nonatomic, retain) UIColor *tintColor; +@property (nonatomic, strong) UIColor *tintColor; @property (nonatomic, copy) NSArray *items; @property (nonatomic,assign,getter=isTranslucent) BOOL translucent; - @end diff --git a/UIKit/Classes/UIToolbar.m b/UIKit/Classes/UIToolbar.m index 54b31289..88852e31 100644 --- a/UIKit/Classes/UIToolbar.m +++ b/UIKit/Classes/UIToolbar.m @@ -33,14 +33,9 @@ #import "UIColor.h" #import "UIGraphics.h" +static const CGFloat kBarHeight = 28; - - - -@interface UIToolbarItem : NSObject { - UIBarButtonItem *item; - UIView *view; -} +@interface UIToolbarItem : NSObject - (id)initWithBarButtonItem:(UIBarButtonItem *)anItem; @@ -51,37 +46,30 @@ - (id)initWithBarButtonItem:(UIBarButtonItem *)anItem; @end @implementation UIToolbarItem -@synthesize item, view; - (id)initWithBarButtonItem:(UIBarButtonItem *)anItem { if ((self=[super init])) { NSAssert((anItem != nil), @"the bar button item must not be nil"); - item = [anItem retain]; + _item = anItem; - if (!item->_isSystemItem && item.customView) { - view = [item.customView retain]; - } else if (!item->_isSystemItem || (item->_systemItem != UIBarButtonSystemItemFixedSpace && item->_systemItem != UIBarButtonSystemItemFlexibleSpace)) { - view = [[UIToolbarButton alloc] initWithBarButtonItem:item]; + if (!_item->_isSystemItem && _item.customView) { + _view = _item.customView; + } else if (!_item->_isSystemItem || (_item->_systemItem != UIBarButtonSystemItemFixedSpace && _item->_systemItem != UIBarButtonSystemItemFlexibleSpace)) { + _view = [[UIToolbarButton alloc] initWithBarButtonItem:_item]; } } return self; } -- (void)dealloc -{ - [item release]; - [view release]; - [super dealloc]; -} - (CGFloat)width { - if (view) { - return view.frame.size.width; - } else if (item->_isSystemItem && item->_systemItem == UIBarButtonSystemItemFixedSpace) { - return item.width; + if (_view) { + return _view.frame.size.width; + } else if (_item->_isSystemItem && _item->_systemItem == UIBarButtonSystemItemFixedSpace) { + return _item.width; } else { return -1; } @@ -96,16 +84,14 @@ - (CGFloat)width -@implementation UIToolbar -@synthesize barStyle=_barStyle, tintColor=_tintColor, translucent=_translucent; - -- (id)init -{ - return [self initWithFrame:CGRectMake(0,0,320,32)]; +@implementation UIToolbar { + NSMutableArray *_toolbarItems; } - (id)initWithFrame:(CGRect)frame { + frame.size.height = kBarHeight; + if ((self=[super initWithFrame:frame])) { _toolbarItems = [[NSMutableArray alloc] init]; self.barStyle = UIBarStyleDefault; @@ -115,13 +101,6 @@ - (id)initWithFrame:(CGRect)frame return self; } -- (void)dealloc -{ - [_tintColor release]; - [_toolbarItems release]; - [super dealloc]; -} - - (void)setBarStyle:(UIBarStyle)newStyle { _barStyle = newStyle; @@ -242,7 +221,6 @@ - (void)setItems:(NSArray *)newItems animated:(BOOL)animated UIToolbarItem *toolbarItem = [[UIToolbarItem alloc] initWithBarButtonItem:item]; [_toolbarItems addObject:toolbarItem]; [self addSubview:toolbarItem.view]; - [toolbarItem release]; } // if animated, fade them in @@ -302,4 +280,19 @@ - (NSString *)description return [NSString stringWithFormat:@"<%@: %p; barStyle = %@; tintColor = %@, isTranslucent = %@>", [self className], self, barStyle, ([self.tintColor description] ?: @"Default"), (self.translucent ? @"YES" : @"NO")]; } +- (UIImage *)backgroundImageForToolbarPosition:(UIToolbarPosition)topOrBottom barMetrics:(UIBarMetrics)barMetrics +{ + return nil; +} + +- (void)setBackgroundImage:(UIImage *)backgroundImage forToolbarPosition:(UIToolbarPosition)topOrBottom barMetrics:(UIBarMetrics)barMetrics +{ +} + +- (CGSize)sizeThatFits:(CGSize)size +{ + size.height = kBarHeight; + return size; +} + @end diff --git a/UIKit/Classes/UIToolbarButton.h b/UIKit/Classes/UIToolbarButton.h index 371b5317..574352fd 100644 --- a/UIKit/Classes/UIToolbarButton.h +++ b/UIKit/Classes/UIToolbarButton.h @@ -31,8 +31,7 @@ @class UIBarButtonItem; -@interface UIToolbarButton : UIButton { -} +@interface UIToolbarButton : UIButton - (id)initWithBarButtonItem:(UIBarButtonItem *)item; diff --git a/UIKit/Classes/UITouch+UIPrivate.h b/UIKit/Classes/UITouch+UIPrivate.h index 2bdbed0f..1c17ed64 100644 --- a/UIKit/Classes/UITouch+UIPrivate.h +++ b/UIKit/Classes/UITouch+UIPrivate.h @@ -29,19 +29,20 @@ #import "UITouch.h" -@class UIView; +@class UIGestureRecognizer; @interface UITouch (UIPrivate) -- (void)_setPhase:(UITouchPhase)phase screenLocation:(CGPoint)screenLocation tapCount:(NSUInteger)tapCount timestamp:(NSTimeInterval)timestamp; -- (void)_updatePhase:(UITouchPhase)phase screenLocation:(CGPoint)screenLocation timestamp:(NSTimeInterval)timestamp; -- (void)_updateGesture:(_UITouchGesture)gesture screenLocation:(CGPoint)screenLocation delta:(CGPoint)delta rotation:(CGFloat)rotation magnification:(CGFloat)magnification timestamp:(NSTimeInterval)timestamp; -- (void)_setDiscreteGesture:(_UITouchGesture)gesture screenLocation:(CGPoint)screenLocation tapCount:(NSUInteger)tapCount delta:(CGPoint)delta timestamp:(NSTimeInterval)timestamp; -- (void)_setTouchedView:(UIView *)view; // sets up the window and gesture recognizers as well -- (void)_removeFromView; // sets the initial view to nil, but leaves window and gesture recognizers alone - used when a view is removed while touch is active -- (void)_setTouchPhaseCancelled; -- (CGPoint)_delta; -- (CGFloat)_rotation; -- (CGFloat)_magnification; -- (UIView *)_previousView; -- (_UITouchGesture)_gesture; +@property (nonatomic, readwrite, assign) NSTimeInterval timestamp; // defaults to now +@property (nonatomic, readwrite, assign) NSUInteger tapCount; // defaults to 0 +@property (nonatomic, readwrite, assign) UITouchPhase phase; // defaults to UITouchPhaseBegan, if changed to UITouchPhaseStationary, also sets previous location to current value of locationInWindow +@property (nonatomic, readwrite, assign) UIView *view; // defaults to nil +@property (nonatomic, readwrite, assign) CGPoint locationOnScreen; // if phase is UITouchPhaseBegan or UITouchPhaseStationary, also sets internal previous location to same value + +@property (nonatomic, readwrite, assign) BOOL wasDeliveredToView; // defaults to NO, used to keep things on the up and up with gesture recognizers that can delay and cancel touches (pure evil) +@property (nonatomic, readwrite, assign) BOOL wasCancelledInView; // defaults to NO, used to keep things on the up and up with gesture recognizers that can delay and cancel touches (pure evil) +@property (nonatomic, readonly) NSTimeInterval beganPhaseTimestamp; // when phase is UITouchPhaseBegan, changes to timestamp property also copied here +@property (nonatomic, readonly) CGPoint beganPhaseLocationOnScreen; // when phase is UITouchPhaseBegan, changes to locationOnScreen property also copied here + +- (void)_addGestureRecognizer:(UIGestureRecognizer *)recognizer; +- (void)_removeGestureRecognizer:(UIGestureRecognizer *)recognizer; @end diff --git a/UIKit/Classes/UITouch.h b/UIKit/Classes/UITouch.h index 3344b1a3..ea27e7cc 100644 --- a/UIKit/Classes/UITouch.h +++ b/UIKit/Classes/UITouch.h @@ -29,55 +29,24 @@ #import -typedef enum { +typedef NS_ENUM(NSInteger, UITouchPhase) { UITouchPhaseBegan, UITouchPhaseMoved, UITouchPhaseStationary, UITouchPhaseEnded, UITouchPhaseCancelled, - _UITouchPhaseGestureBegan, - _UITouchPhaseGestureChanged, - _UITouchPhaseGestureEnded, - _UITouchPhaseDiscreteGesture -} UITouchPhase; - -typedef enum { - _UITouchGestureUnknown = 0, - _UITouchGesturePan, // maps only to touch-enabled scrolling devices like magic trackpad, etc. for older wheels, use _UITouchGestureScrollWheel - _UITouchGestureRotation, // only works for touch-enabled input devices - _UITouchGesturePinch, // only works for touch-enabled input devices - _UITouchGestureSwipe, // only works for touch-enabled input devices (this is actually discrete, but OSX sends gesture begin/end events around it) - _UITouchDiscreteGestureRightClick, // should be pretty obvious - _UITouchDiscreteGestureScrollWheel, // this is used by old fashioned wheel mice or when the OS sends its automatic momentum scroll events - _UITouchDiscreteGestureMouseMove // the mouse moved but wasn't in a gesture or the button was not being held down -} _UITouchGesture; +}; @class UIView, UIWindow; -@interface UITouch : NSObject { -@private - NSTimeInterval _timestamp; - NSUInteger _tapCount; - UITouchPhase _phase; - _UITouchGesture _gesture; - CGPoint _delta; - CGFloat _rotation; - CGFloat _magnification; - CGPoint _location; - CGPoint _previousLocation; - UIView *_view; - UIWindow *_window; - NSArray *_gestureRecognizers; -} - +@interface UITouch : NSObject - (CGPoint)locationInView:(UIView *)inView; - (CGPoint)previousLocationInView:(UIView *)inView; @property (nonatomic, readonly) NSTimeInterval timestamp; @property (nonatomic, readonly) NSUInteger tapCount; @property (nonatomic, readonly) UITouchPhase phase; -@property (nonatomic, readonly, retain) UIView *view; -@property (nonatomic, readonly, retain) UIWindow *window; -@property (nonatomic,readonly,copy) NSArray *gestureRecognizers; - +@property (nonatomic, readonly, strong) UIView *view; +@property (nonatomic, readonly, strong) UIWindow *window; +@property (nonatomic, readonly, copy) NSArray *gestureRecognizers; @end diff --git a/UIKit/Classes/UITouch.m b/UIKit/Classes/UITouch.m index 1c9852d8..3dcb8fe4 100644 --- a/UIKit/Classes/UITouch.m +++ b/UIKit/Classes/UITouch.m @@ -29,197 +29,149 @@ #import "UITouch+UIPrivate.h" #import "UIWindow.h" -#import "UIGestureRecognizerSubclass.h" -#import +#import "UIView+UIPrivate.h" -static NSArray *GestureRecognizersForView(UIView *view) -{ - NSMutableArray *recognizers = [[NSMutableArray alloc] initWithCapacity:0]; - - while (view) { - [recognizers addObjectsFromArray:view.gestureRecognizers]; - view = [view superview]; - } - - return [recognizers autorelease]; +@implementation UITouch { + CGPoint _locationOnScreen; + CGPoint _previousLocationOnScreen; + NSMutableArray *_gestureRecognizers; + BOOL _wasDeliveredToView; + BOOL _wasCancelledInView; + NSTimeInterval _beganPhaseTimestamp; + CGPoint _beganPhaseLocationOnScreen; } -@implementation UITouch -@synthesize timestamp=_timestamp, tapCount=_tapCount, phase=_phase, view=_view, window=_window, gestureRecognizers=_gestureRecognizers; - - (id)init { if ((self=[super init])) { - _phase = UITouchPhaseCancelled; - _gesture = _UITouchGestureUnknown; + _phase = UITouchPhaseBegan; + _timestamp = [NSDate timeIntervalSinceReferenceDate]; + _gestureRecognizers = [NSMutableArray new]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_viewDidMoveToSuperviewNotification:) name:UIViewDidMoveToSuperviewNotification object:nil]; } return self; } - (void)dealloc { - [_window release]; - [_view release]; - [_gestureRecognizers release]; - [super dealloc]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIViewDidMoveToSuperviewNotification object:nil]; } +- (void)_viewDidMoveToSuperviewNotification:(NSNotification *)notification +{ + if ([_view isDescendantOfView:[notification object]]) { + _view = nil; + } +} - - -- (void)_setPhase:(UITouchPhase)phase screenLocation:(CGPoint)screenLocation tapCount:(NSUInteger)tapCount timestamp:(NSTimeInterval)timestamp; +- (void)setTimestamp:(NSTimeInterval)timestamp { - _phase = phase; - _gesture = _UITouchGestureUnknown; - _previousLocation = _location = screenLocation; - _tapCount = tapCount; _timestamp = timestamp; - _rotation = 0; - _magnification = 0; + + if (_phase == UITouchPhaseBegan) { + _beganPhaseTimestamp = timestamp; + } } -- (void)_updatePhase:(UITouchPhase)phase screenLocation:(CGPoint)screenLocation timestamp:(NSTimeInterval)timestamp; +- (void)setTapCount:(NSUInteger)tapCount { - if (!CGPointEqualToPoint(screenLocation, _location)) { - _previousLocation = _location; - _location = screenLocation; - } - - _phase = phase; - _timestamp = timestamp; + _tapCount = tapCount; } -- (void)_updateGesture:(_UITouchGesture)gesture screenLocation:(CGPoint)screenLocation delta:(CGPoint)delta rotation:(CGFloat)rotation magnification:(CGFloat)magnification timestamp:(NSTimeInterval)timestamp; +- (void)setPhase:(UITouchPhase)phase { - if (!CGPointEqualToPoint(screenLocation, _location)) { - _previousLocation = _location; - _location = screenLocation; - } - - _phase = _UITouchPhaseGestureChanged; + _phase = phase; - _gesture = gesture; - _delta = delta; - _rotation = rotation; - _magnification = magnification; - _timestamp = timestamp; + if (phase == UITouchPhaseStationary || phase == UITouchPhaseBegan) { + _previousLocationOnScreen = _locationOnScreen; + } } -- (void)_setDiscreteGesture:(_UITouchGesture)gesture screenLocation:(CGPoint)screenLocation tapCount:(NSUInteger)tapCount delta:(CGPoint)delta timestamp:(NSTimeInterval)timestamp; +- (void)setView:(UIView *)view { - _phase = _UITouchPhaseDiscreteGesture; - _gesture = gesture; - _previousLocation = _location = screenLocation; - _tapCount = tapCount; - _delta = delta; - _timestamp = timestamp; - _rotation = 0; - _magnification = 0; + _view = view; + _window = view.window; } -- (_UITouchGesture)_gesture +- (CGPoint)locationOnScreen { - return _gesture; + return _locationOnScreen; } -- (void)_setTouchedView:(UIView *)view +- (void)setLocationOnScreen:(CGPoint)locationOnScreen { - if (_view != view) { - [_view release]; - _view = [view retain]; - } + _previousLocationOnScreen = _locationOnScreen; + _locationOnScreen = locationOnScreen; - if (_window != view.window) { - [_window release]; - _window = [view.window retain]; + if (_phase == UITouchPhaseStationary || _phase == UITouchPhaseBegan) { + _previousLocationOnScreen = locationOnScreen; + } + + if (_phase == UITouchPhaseBegan) { + _beganPhaseLocationOnScreen = locationOnScreen; } +} - [_gestureRecognizers release]; - _gestureRecognizers = [GestureRecognizersForView(_view) copy]; +- (BOOL)wasDeliveredToView +{ + return _wasDeliveredToView; } -- (void)_removeFromView +- (void)setWasDeliveredToView:(BOOL)wasDeliveredToView { - NSMutableArray *remainingRecognizers = [_gestureRecognizers mutableCopy]; + _wasDeliveredToView = wasDeliveredToView; +} - // if the view is being removed from this touch, we need to remove/cancel any gesture recognizers that belong to the view - // being removed. this kinda feels like the wrong place for this, but the touch itself has a list of potential gesture - // recognizers attached to it so an active touch only considers the recongizers that were present at the point the touch - // first touched the screen. it could easily have recognizers attached to it from superviews of the view being removed so - // we can't just cancel them all. the view itself could cancel its own recognizers, but then it needs a way to remove them - // from an active touch so in a sense we're right back where we started. so I figured we might as well just take care of it - // here and see what happens. - for (UIGestureRecognizer *recognizer in _gestureRecognizers) { - if (recognizer.view == _view) { - if (recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged) { - recognizer.state = UIGestureRecognizerStateCancelled; - } - [remainingRecognizers removeObject:recognizer]; - } - } - - [_gestureRecognizers release]; - _gestureRecognizers = [remainingRecognizers copy]; - [remainingRecognizers release]; - - [_view release]; - _view = nil; +- (BOOL)wasCancelledInView +{ + return _wasCancelledInView; } -- (void)_setTouchPhaseCancelled +- (void)setWasCancelledInView:(BOOL)wasCancelledInView { - _phase = UITouchPhaseCancelled; + _wasCancelledInView = wasCancelledInView; } -- (CGPoint)_delta +- (NSTimeInterval)beganPhaseTimestamp { - return _delta; + return _beganPhaseTimestamp; } -- (CGFloat)_rotation +- (CGPoint)beganPhaseLocationOnScreen { - return _rotation; + return _beganPhaseLocationOnScreen; } -- (CGFloat)_magnification +- (NSArray *)gestureRecognizers { - return _magnification; + return [_gestureRecognizers copy]; } -- (UIWindow *)window +- (void)_addGestureRecognizer:(UIGestureRecognizer *)gesture { - return _window; + [_gestureRecognizers addObject:gesture]; } -- (CGPoint)_convertLocationPoint:(CGPoint)thePoint toView:(UIView *)inView +- (void)_removeGestureRecognizer:(UIGestureRecognizer *)gesture { - UIWindow *window = self.window; - - // The stored location should always be in the coordinate space of the UIScreen that contains the touch's window. - // So first convert from the screen to the window: - CGPoint point = [window convertPoint:thePoint fromWindow:nil]; - - // Then convert to the desired location (if any). - if (inView) { - point = [inView convertPoint:point fromView:window]; - } - - return point; + [_gestureRecognizers removeObject:gesture]; } - (CGPoint)locationInView:(UIView *)inView { - return [self _convertLocationPoint:_location toView:inView]; + return [self.window convertPoint:[self.window convertPoint:_locationOnScreen fromWindow:nil] toView:inView]; } - (CGPoint)previousLocationInView:(UIView *)inView { - return [self _convertLocationPoint:_previousLocation toView:inView]; + return [self.window convertPoint:[self.window convertPoint:_previousLocationOnScreen fromWindow:nil] toView:inView]; } - (NSString *)description { NSString *phase = @""; + switch (self.phase) { case UITouchPhaseBegan: phase = @"Began"; @@ -236,19 +188,8 @@ - (NSString *)description case UITouchPhaseCancelled: phase = @"Cancelled"; break; - case _UITouchPhaseGestureBegan: - phase = @"GestureBegan"; - break; - case _UITouchPhaseGestureChanged: - phase = @"GestureChanged"; - break; - case _UITouchPhaseGestureEnded: - phase = @"GestureEnded"; - break; - case _UITouchPhaseDiscreteGesture: - phase = @"DiscreteGesture"; - break; } + return [NSString stringWithFormat:@"<%@: %p; timestamp = %e; tapCount = %lu; phase = %@; view = %@; window = %@>", [self className], self, self.timestamp, (unsigned long)self.tapCount, phase, self.view, self.window]; } diff --git a/UIKit/Classes/UIEvent+UIPrivate.h b/UIKit/Classes/UITouchEvent.h similarity index 53% rename from UIKit/Classes/UIEvent+UIPrivate.h rename to UIKit/Classes/UITouchEvent.h index 709bf4a8..70477676 100644 --- a/UIKit/Classes/UIEvent+UIPrivate.h +++ b/UIKit/Classes/UITouchEvent.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -29,10 +29,37 @@ #import "UIEvent.h" -@interface UIEvent (UIPrivate) -- (id)initWithEventType:(UIEventType)type; -- (void)_setTouch:(UITouch *)touch; -- (void)_setTimestamp:(NSTimeInterval)timestamp; -- (void)_setUnhandledKeyPressEvent; -- (BOOL)_isUnhandledKeyPressEvent; +@class UITouch; + +typedef NS_ENUM(NSInteger, UITouchEventGesture) { + UITouchEventGestureNone, // a normal click-drag touch (not a standard OSX gesture) + + // handle standard OSX gestures + UITouchEventGestureBegin, // when OSX sends the begin gesture event, but hasn't identified the exact gesture yet + UITouchEventGesturePinch, + UITouchEventGestureRotate, + UITouchEventGesturePan, + + // discrete gestures that violate all the rules + UITouchEventGestureScrollWheel, + UITouchEventGestureRightClick, + UITouchEventGestureMouseMove, + UITouchEventGestureMouseEntered, + UITouchEventGestureMouseExited, + UITouchEventGestureSwipe, +}; + +@interface UITouchEvent : UIEvent +- (id)initWithTouch:(UITouch *)touch; +- (void)endTouchEvent; + +@property (nonatomic, readonly, strong) UITouch *touch; +@property (nonatomic, readwrite, assign) UITouchEventGesture touchEventGesture; // default UITouchEventGestureNone +@property (nonatomic, readonly) BOOL isDiscreteGesture; // YES for the mouse UITouchEventGesture types + +// used for the various OSX gestures +@property (nonatomic, readwrite, assign) CGPoint translation; +@property (nonatomic, readwrite, assign) CGFloat rotation; +@property (nonatomic, readwrite, assign) CGFloat magnification; + @end diff --git a/UIKit/Classes/UIApplication+UIPrivate.h b/UIKit/Classes/UITouchEvent.m similarity index 57% rename from UIKit/Classes/UIApplication+UIPrivate.h rename to UIKit/Classes/UITouchEvent.m index 75a59b6c..bd35d6f6 100644 --- a/UIKit/Classes/UIApplication+UIPrivate.h +++ b/UIKit/Classes/UITouchEvent.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. + * Copyright (c) 2013, 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: @@ -27,20 +27,51 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIApplication.h" - -@class UIWindow, UIScreen, NSEvent, UIPopoverController; - -@interface UIApplication (UIPrivate) -- (void)_setKeyWindow:(UIWindow *)newKeyWindow; -- (void)_windowDidBecomeVisible:(UIWindow *)theWindow; -- (void)_windowDidBecomeHidden:(UIWindow *)theWindow; -- (BOOL)_sendGlobalKeyboardNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *)theScreen; // checks for CMD-Return/Enter and returns YES if it was handled, NO if not -- (BOOL)_sendKeyboardNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *)theScreen; // returns YES if it was handled within UIKit (first calls _sendGlobalKeyboardNSEvent:fromScreen:) -- (void)_sendMouseNSEvent:(NSEvent *)theNSEvent fromScreen:(UIScreen *)theScreen; -- (void)_cancelTouches; -- (void)_removeViewFromTouches:(UIView *)aView; -- (UIResponder *)_firstResponderForScreen:(UIScreen *)screen; -- (BOOL)_firstResponderCanPerformAction:(SEL)action withSender:(id)sender fromScreen:(UIScreen *)theScreen; -- (BOOL)_sendActionToFirstResponder:(SEL)action withSender:(id)sender fromScreen:(UIScreen *)theScreen; +#import "UITouchEvent.h" +#import "UITouch.h" +#import "UIGestureRecognizer+UIPrivate.h" + +@implementation UITouchEvent + +- (id)initWithTouch:(UITouch *)touch +{ + if ((self=[super init])) { + _touch = touch; + _touchEventGesture = UITouchEventGestureNone; + } + return self; +} + +- (NSTimeInterval)timestamp +{ + return _touch.timestamp; +} + +- (NSSet *)allTouches +{ + return [NSSet setWithObject:_touch]; +} + +- (UIEventType)type +{ + return UIEventTypeTouches; +} + +- (BOOL)isDiscreteGesture +{ + return (_touchEventGesture == UITouchEventGestureScrollWheel || + _touchEventGesture == UITouchEventGestureRightClick || + _touchEventGesture == UITouchEventGestureMouseMove || + _touchEventGesture == UITouchEventGestureMouseEntered || + _touchEventGesture == UITouchEventGestureMouseExited || + _touchEventGesture == UITouchEventGestureSwipe); +} + +- (void)endTouchEvent +{ + for (UIGestureRecognizer *gesture in _touch.gestureRecognizers) { + [gesture _endTrackingTouch:_touch withEvent:self]; + } +} + @end diff --git a/UIKit/Classes/UITransitionView.h b/UIKit/Classes/UITransitionView.h deleted file mode 100644 index 50e86d71..00000000 --- a/UIKit/Classes/UITransitionView.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ - -#import "UIView.h" - -typedef enum { - UITransitionNone = 0, // no animation is done - UITransitionFromLeft, // the new view slides in from the left over top of the old view - UITransitionFromRight, // the new view slides in from the right over top of the old view - UITransitionFromTop, // the new view slides in from the top over top of the old view - UITransitionFromBottom, // the new view slides in from the bottom over top of the old view - UITransitionPushLeft, // the new view slides in from the right and pushes the old view off the left - UITransitionPushRight, // the new view slides in from the left and pushes the old view off the right - UITransitionPushUp, // the new view slides in from the bottom and pushes the old view off the top - UITransitionPushDown, // the new view slides in from the top and pushes the old view off the bottom - UITransitionCrossFade, // new view fades in as old view fades out - UITransitionFadeIn, // new view fades in over old view - UITransitionFadeOut // old view fades out to reveal the new view behind it -} UITransition; - -@class UITransitionView; - -@protocol UITransitionViewDelegate -- (void)transitionView:(UITransitionView *)transitionView didTransitionFromView:(UIView *)fromView toView:(UIView *)toView withTransition:(UITransition)transition; -@end - -@interface UITransitionView : UIView { - UITransition _transition; - UIView *_view; - __unsafe_unretained id _delegate; -} - -- (id)initWithFrame:(CGRect)frame view:(UIView *)aView; - -@property (nonatomic, retain) UIView *view; -@property (nonatomic, assign) UITransition transition; -@property (nonatomic, assign) id delegate; - -@end diff --git a/UIKit/Classes/UITransitionView.m b/UIKit/Classes/UITransitionView.m deleted file mode 100644 index 3308b532..00000000 --- a/UIKit/Classes/UITransitionView.m +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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. - */ - -#import "UITransitionView.h" - -@implementation UITransitionView -@synthesize view=_view, transition=_transition, delegate=_delegate; - -- (id)initWithFrame:(CGRect)frame view:(UIView *)aView -{ - if ((self=[super initWithFrame:frame])) { - self.view = aView; - } - return self; -} - -- (void)dealloc -{ - [_view release]; - [super dealloc]; -} - -- (void)setFrame:(CGRect)frame -{ - [super setFrame:frame]; - _view.frame = self.bounds; -} - -- (CGRect)_rectForIncomingView -{ - switch (_transition) { - case UITransitionPushRight: - case UITransitionFromLeft: return CGRectOffset(self.bounds,-self.bounds.size.width,0); - case UITransitionPushLeft: - case UITransitionFromRight: return CGRectOffset(self.bounds,self.bounds.size.width,0); - case UITransitionPushDown: - case UITransitionFromTop: return CGRectOffset(self.bounds,0,-self.bounds.size.height); - case UITransitionPushUp: - case UITransitionFromBottom: return CGRectOffset(self.bounds,0,self.bounds.size.height); - default: return self.bounds; - } -} - -- (CGRect)_rectForOutgoingView -{ - switch (_transition) { - case UITransitionPushLeft: return CGRectOffset(self.bounds,-self.bounds.size.width,0); - case UITransitionPushRight: return CGRectOffset(self.bounds,self.bounds.size.width,0); - case UITransitionPushDown: return CGRectOffset(self.bounds,0,self.bounds.size.height); - case UITransitionPushUp: return CGRectOffset(self.bounds,0,-self.bounds.size.height); - default: return self.bounds; - } -} - -- (void)_finishTransition:(NSDictionary *)info -{ - UIView *fromView = [info objectForKey:@"fromView"]; - UIView *toView = [info objectForKey:@"toView"]; - UITransition transition = [[info objectForKey:@"transition"] intValue]; - - [fromView removeFromSuperview]; - - [_delegate transitionView:self didTransitionFromView:fromView toView:toView withTransition:transition]; -} - -- (void)setView:(UIView *)aView -{ - if (aView != _view) { - aView.frame = [self _rectForIncomingView]; - [self addSubview:aView]; - - NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: - _view, @"fromView", - aView, @"toView", - [NSNumber numberWithInt:_transition], @"transition", - nil]; - - if (_transition == UITransitionNone) { - [self _finishTransition:info]; - } else { - if (_transition == UITransitionFadeOut) { - [self sendSubviewToBack:aView]; - } else if (_transition == UITransitionFadeIn) { - aView.alpha = 0; - } - - [UIView animateWithDuration:0.33 - animations:^(void) { - _view.frame = [self _rectForOutgoingView]; - aView.frame = self.bounds; - - if (_transition == UITransitionFadeOut || _transition == UITransitionCrossFade) { - _view.alpha = 0; - } - - if (_transition == UITransitionFadeIn || _transition == UITransitionCrossFade) { - aView.alpha = 1; - } - } - completion:^(BOOL finished) { - [self _finishTransition:info]; - }]; - } - - [_view release]; - _view = [aView retain]; - } -} - -@end diff --git a/UIKit/Classes/UIView.h b/UIKit/Classes/UIView.h index 655518bc..13b194e9 100644 --- a/UIKit/Classes/UIView.h +++ b/UIKit/Classes/UIView.h @@ -31,7 +31,7 @@ #import "UIGeometry.h" #import "UIAppearance.h" -enum { +typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, @@ -40,9 +40,8 @@ enum { UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5 }; -typedef NSUInteger UIViewAutoresizing; -typedef enum { +typedef NS_ENUM(NSInteger, UIViewContentMode) { UIViewContentModeScaleToFill, UIViewContentModeScaleAspectFit, UIViewContentModeScaleAspectFill, @@ -56,24 +55,24 @@ typedef enum { UIViewContentModeTopRight, UIViewContentModeBottomLeft, UIViewContentModeBottomRight, -} UIViewContentMode; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIViewAnimationCurve) { UIViewAnimationCurveEaseInOut, UIViewAnimationCurveEaseIn, UIViewAnimationCurveEaseOut, UIViewAnimationCurveLinear -} UIViewAnimationCurve; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIViewAnimationTransition) { UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFromLeft, UIViewAnimationTransitionFlipFromRight, UIViewAnimationTransitionCurlUp, UIViewAnimationTransitionCurlDown, -} UIViewAnimationTransition; +}; -enum { +typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) { UIViewAnimationOptionLayoutSubviews = 1 << 0, // not currently supported UIViewAnimationOptionAllowUserInteraction = 1 << 1, UIViewAnimationOptionBeginFromCurrentState = 1 << 2, @@ -82,46 +81,26 @@ enum { UIViewAnimationOptionOverrideInheritedDuration = 1 << 5, // not currently supported UIViewAnimationOptionOverrideInheritedCurve = 1 << 6, // not currently supported UIViewAnimationOptionAllowAnimatedContent = 1 << 7, // not currently supported - UIViewAnimationOptionShowHideTransitionViews = 1 << 8, // not currently supported + UIViewAnimationOptionShowHideTransitionViews = 1 << 8, UIViewAnimationOptionCurveEaseInOut = 0 << 16, UIViewAnimationOptionCurveEaseIn = 1 << 16, UIViewAnimationOptionCurveEaseOut = 2 << 16, UIViewAnimationOptionCurveLinear = 3 << 16, - UIViewAnimationOptionTransitionNone = 0 << 20, // not currently supported - UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20, // not currently supported - UIViewAnimationOptionTransitionFlipFromRight = 2 << 20, // not currently supported - UIViewAnimationOptionTransitionCurlUp = 3 << 20, // not currently supported - UIViewAnimationOptionTransitionCurlDown = 4 << 20, // not currently supported - UIViewAnimationOptionTransitionCrossDissolve = 5 << 20, // not currently supported - UIViewAnimationOptionTransitionFlipFromTop = 6 << 20, // not currently supported - UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20, // not currently supported + UIViewAnimationOptionTransitionNone = 0 << 20, + UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20, + UIViewAnimationOptionTransitionFlipFromRight = 2 << 20, + UIViewAnimationOptionTransitionCurlUp = 3 << 20, + UIViewAnimationOptionTransitionCurlDown = 4 << 20, + UIViewAnimationOptionTransitionCrossDissolve = 5 << 20, + UIViewAnimationOptionTransitionFlipFromTop = 6 << 20, + UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20, }; -typedef NSUInteger UIViewAnimationOptions; @class UIColor, CALayer, UIViewController, UIGestureRecognizer; -@interface UIView : UIResponder { -@private - UIView *_superview; - NSMutableSet *_subviews; - BOOL _clearsContextBeforeDrawing; - BOOL _autoresizesSubviews; - BOOL _userInteractionEnabled; - CALayer *_layer; - NSInteger _tag; - UIViewContentMode _contentMode; - UIColor *_backgroundColor; - BOOL _implementsDrawRect; - BOOL _multipleTouchEnabled; - BOOL _exclusiveTouch; - UIViewController *_viewController; - UIViewAutoresizing _autoresizingMask; - BOOL _needsDidAppearOrDisappear; - NSMutableSet *_gestureRecognizers; -} - +@interface UIView : UIResponder + (Class)layerClass; - (id)initWithFrame:(CGRect)frame; @@ -163,7 +142,6 @@ typedef NSUInteger UIViewAnimationOptions; + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion; + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations; -// the block-based transition methods are not currently implemented + (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion; + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion; @@ -205,6 +183,5 @@ typedef NSUInteger UIViewAnimationOptions; @property (nonatomic) CGFloat contentScaleFactor; @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, copy) NSArray *gestureRecognizers; @end diff --git a/UIKit/Classes/UIView.m b/UIKit/Classes/UIView.m index ecdc0d27..8e2fb72b 100644 --- a/UIKit/Classes/UIView.m +++ b/UIKit/Classes/UIView.m @@ -30,14 +30,12 @@ #import "UIView+UIPrivate.h" #import "UIWindow.h" #import "UIGraphics.h" -#import "UIColor.h" #import "UIViewLayoutManager.h" #import "UIViewAnimationGroup.h" -#import "UIViewBlockAnimationDelegate.h" #import "UIViewController.h" #import "UIAppearanceInstance.h" -#import "UIApplication+UIPrivate.h" #import "UIGestureRecognizer+UIPrivate.h" +#import "UIApplicationAppKitIntegration.h" #import "UIScreen.h" #import "UIColor+UIPrivate.h" #import "UIColorRep.h" @@ -51,10 +49,13 @@ static NSMutableArray *_animationGroups; static BOOL _animationsEnabled = YES; -@implementation UIView -@synthesize layer=_layer, superview=_superview, clearsContextBeforeDrawing=_clearsContextBeforeDrawing, autoresizesSubviews=_autoresizesSubviews; -@synthesize tag=_tag, userInteractionEnabled=_userInteractionEnabled, contentMode=_contentMode, backgroundColor=_backgroundColor; -@synthesize multipleTouchEnabled=_multipleTouchEnabled, exclusiveTouch=_exclusiveTouch, autoresizingMask=_autoresizingMask; +@implementation UIView { + __unsafe_unretained UIView *_superview; + __unsafe_unretained UIViewController *_viewController; + NSMutableSet *_subviews; + BOOL _implementsDrawRect; + NSMutableSet *_gestureRecognizers; +} + (void)initialize { @@ -81,14 +82,14 @@ - (id)init - (id)initWithFrame:(CGRect)theFrame { if ((self=[super init])) { - _implementsDrawRect = [isa _instanceImplementsDrawRect]; + _implementsDrawRect = [[self class] _instanceImplementsDrawRect]; _clearsContextBeforeDrawing = YES; _autoresizesSubviews = YES; _userInteractionEnabled = YES; _subviews = [[NSMutableSet alloc] init]; _gestureRecognizers = [[NSMutableSet alloc] init]; - _layer = [[[isa layerClass] alloc] init]; + _layer = [[[[self class] layerClass] alloc] init]; _layer.delegate = self; _layer.layoutManager = [UIViewLayoutManager layoutManager]; @@ -104,18 +105,12 @@ - (id)initWithFrame:(CGRect)theFrame - (void)dealloc { - [[_subviews allObjects] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [_gestureRecognizers makeObjectsPerformSelector:@selector(_setView:) withObject:nil]; + [[_subviews allObjects] makeObjectsPerformSelector:@selector(_removeFromDeallocatedSuperview)]; _layer.layoutManager = nil; _layer.delegate = nil; [_layer removeFromSuperlayer]; - - [_subviews release]; - [_layer release]; - [_backgroundColor release]; - [_gestureRecognizers release]; - - [super dealloc]; } - (void)_setViewController:(UIViewController *)theViewController @@ -138,7 +133,7 @@ - (UIResponder *)nextResponder return (UIResponder *)[self _viewController] ?: (UIResponder *)_superview; } -- (id)_appearanceContainer +- (id)_UIAppearanceContainer { return self.superview; } @@ -172,12 +167,14 @@ - (void)_willMoveFromWindow:(UIWindow *)fromWindow toWindow:(UIWindow *)toWindow [self resignFirstResponder]; } - [self _setAppearanceNeedsUpdate]; + [self _UIAppearanceSetNeedsUpdate]; [self willMoveToWindow:toWindow]; for (UIView *subview in self.subviews) { [subview _willMoveFromWindow:fromWindow toWindow:toWindow]; } + + [[self _viewController] beginAppearanceTransition:(toWindow != nil) animated:NO]; } } @@ -202,22 +199,30 @@ - (void)_didMoveFromWindow:(UIWindow *)fromWindow toWindow:(UIWindow *)toWindow for (UIView *subview in self.subviews) { [subview _didMoveFromWindow:fromWindow toWindow:toWindow]; } - } -} - -- (BOOL)_subviewControllersNeedAppearAndDisappear -{ - UIView *view = self; - - while (view) { - if ([view _viewController] != nil) { - return NO; - } else { - view = [view superview]; + + UIViewController *controller = [self _viewController]; + + if (controller) { + if ([[self class] _isAnimating]) { + void (^completionBlock)(BOOL) = [[self class] _animationCompletionBlock]; + + [[self class] _setAnimationCompletionBlock:^(BOOL finished) { + [controller endAppearanceTransition]; + + if (completionBlock) { + completionBlock(finished); + } + }]; + } else { + // this is sort of strange, but testing against iOS 6 seems to indicate that appearance transitions + // that don't occur within an animation block still do something like this.. it waits until the runloop + // cycles before really finishing. I can think of some good reasons for this behavior, so I think it + // makes sense to try to replicate it, but I know the real thing doesn't do it like this... :/ + // (although to be fair, the real thing doesn't do anything much like I'm doing it, so...) + [controller performSelector:@selector(endAppearanceTransition) withObject:nil afterDelay:0]; + } } } - - return YES; } - (void)addSubview:(UIView *)subview @@ -228,31 +233,19 @@ - (void)addSubview:(UIView *)subview UIWindow *oldWindow = subview.window; UIWindow *newWindow = self.window; - subview->_needsDidAppearOrDisappear = [self _subviewControllersNeedAppearAndDisappear]; - - if ([subview _viewController] && subview->_needsDidAppearOrDisappear) { - [[subview _viewController] viewWillAppear:NO]; - } - [subview _willMoveFromWindow:oldWindow toWindow:newWindow]; [subview willMoveToSuperview:self]; - { - [subview retain]; - - if (subview.superview) { - [subview.layer removeFromSuperlayer]; - [subview.superview->_subviews removeObject:subview]; - } - - [subview willChangeValueForKey:@"superview"]; - [_subviews addObject:subview]; - subview->_superview = self; - [_layer addSublayer:subview.layer]; - [subview didChangeValueForKey:@"superview"]; - - [subview release]; + if (subview.superview) { + [subview.layer removeFromSuperlayer]; + [subview.superview->_subviews removeObject:subview]; } + + [subview willChangeValueForKey:@"superview"]; + [_subviews addObject:subview]; + subview->_superview = self; + [_layer addSublayer:subview.layer]; + [subview didChangeValueForKey:@"superview"]; if (oldWindow.screen != newWindow.screen) { [subview _didMoveToScreen]; @@ -264,10 +257,6 @@ - (void)addSubview:(UIView *)subview [[NSNotificationCenter defaultCenter] postNotificationName:UIViewDidMoveToSuperviewNotification object:subview]; [self didAddSubview:subview]; - - if ([subview _viewController] && subview->_needsDidAppearOrDisappear) { - [[subview _viewController] viewDidAppear:NO]; - } } } @@ -303,19 +292,24 @@ - (void)sendSubviewToBack:(UIView *)subview } } +- (void)_abortGestureRecognizers +{ + // note - the real UIKit supports multitouch so it only really interruptes the current touch + // and not all of them, but this is easier for now since we don't support that anyway. + UIApplicationInterruptTouchesInView(self); +} + +- (void)_removeFromDeallocatedSuperview +{ + _superview = nil; + [self _abortGestureRecognizers]; +} + - (void)removeFromSuperview { if (_superview) { - [self retain]; - - [[UIApplication sharedApplication] _removeViewFromTouches:self]; - UIWindow *oldWindow = self.window; - - if (_needsDidAppearOrDisappear && [self _viewController]) { - [[self _viewController] viewWillDisappear:NO]; - } - + [_superview willRemoveSubview:self]; [self _willMoveFromWindow:oldWindow toWindow:nil]; [self willMoveToSuperview:nil]; @@ -325,16 +319,13 @@ - (void)removeFromSuperview [_superview->_subviews removeObject:self]; _superview = nil; [self didChangeValueForKey:@"superview"]; - + + [self _abortGestureRecognizers]; + + [[NSNotificationCenter defaultCenter] postNotificationName:UIViewDidMoveToSuperviewNotification object:self]; + [self _didMoveFromWindow:oldWindow toWindow:nil]; [self didMoveToSuperview]; - [[NSNotificationCenter defaultCenter] postNotificationName:UIViewDidMoveToSuperviewNotification object:self]; - - if (_needsDidAppearOrDisappear && [self _viewController]) { - [[self _viewController] viewDidDisappear:NO]; - } - - [self release]; } } @@ -763,9 +754,9 @@ - (void)setOpaque:(BOOL)newO - (void)setBackgroundColor:(UIColor *)newColor { if (_backgroundColor != newColor) { - [_backgroundColor release]; - _backgroundColor = [newColor retain]; + _backgroundColor = newColor; self.opaque = [_backgroundColor _isOpaque]; + [self setNeedsDisplay]; } } @@ -841,10 +832,13 @@ - (void)layoutSubviews - (void)_layoutSubviews { - [self _updateAppearanceIfNeeded]; + const BOOL wereEnabled = [UIView areAnimationsEnabled]; + [UIView setAnimationsEnabled:NO]; + [self _UIAppearanceUpdateIfNeeded]; [[self _viewController] viewWillLayoutSubviews]; [self layoutSubviews]; [[self _viewController] viewDidLayoutSubviews]; + [UIView setAnimationsEnabled:wereEnabled]; } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event @@ -852,9 +846,24 @@ - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event return CGRectContainsPoint(self.bounds, point); } +- (BOOL)_isAnimatedUserInteractionEnabled +{ + for (UIViewAnimationGroup *group in _animationGroups) { + if (!group.allowUserInteraction) { + for (UIView *animatingView in group.allAnimatingViews) { + if ([self isDescendantOfView:animatingView]) { + return NO; + } + } + } + } + + return YES; +} + - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { - if (self.hidden || !self.userInteractionEnabled || self.alpha < 0.01 || ![self pointInside:point withEvent:event]) { + if (self.hidden || !self.userInteractionEnabled || self.alpha < 0.01 || ![self pointInside:point withEvent:event] || ![self _isAnimatedUserInteractionEnabled]) { return nil; } else { for (UIView *subview in [self.subviews reverseObjectEnumerator]) { @@ -972,54 +981,54 @@ - (NSArray *)gestureRecognizers return [_gestureRecognizers allObjects]; } ++ (void)_beginAnimationsWithOptions:(UIViewAnimationOptions)options +{ + [_animationGroups addObject:[[UIViewAnimationGroup alloc] initWithAnimationOptions:options]]; +} + ++ (void)_setAnimationName:(NSString *)name context:(void *)context +{ + [[_animationGroups lastObject] setName:name]; + [[_animationGroups lastObject] setContext:context]; +} + ++ (void)_setAnimationCompletionBlock:(void (^)(BOOL finished))completion +{ + [(UIViewAnimationGroup *)[_animationGroups lastObject] setCompletionBlock:completion]; +} + ++ (void (^)(BOOL))_animationCompletionBlock +{ + return [(UIViewAnimationGroup *)[_animationGroups lastObject] completionBlock]; +} + ++ (void)_setAnimationTransitionView:(UIView *)view +{ + [[_animationGroups lastObject] setTransitionView:view shouldCache:NO]; +} + ++ (BOOL)_isAnimating +{ + return ([_animationGroups count] != 0); +} + + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion { - const BOOL ignoreInteractionEvents = !((options & UIViewAnimationOptionAllowUserInteraction) == UIViewAnimationOptionAllowUserInteraction); - const BOOL repeatAnimation = ((options & UIViewAnimationOptionRepeat) == UIViewAnimationOptionRepeat); - const BOOL autoreverseRepeat = ((options & UIViewAnimationOptionAutoreverse) == UIViewAnimationOptionAutoreverse); - const BOOL beginFromCurrentState = ((options & UIViewAnimationOptionBeginFromCurrentState) == UIViewAnimationOptionBeginFromCurrentState); - UIViewAnimationCurve animationCurve; - - if ((options & UIViewAnimationOptionCurveEaseInOut) == UIViewAnimationOptionCurveEaseInOut) { - animationCurve = UIViewAnimationCurveEaseInOut; - } else if ((options & UIViewAnimationOptionCurveEaseIn) == UIViewAnimationOptionCurveEaseIn) { - animationCurve = UIViewAnimationCurveEaseIn; - } else if ((options & UIViewAnimationOptionCurveEaseOut) == UIViewAnimationOptionCurveEaseOut) { - animationCurve = UIViewAnimationCurveEaseOut; - } else { - animationCurve = UIViewAnimationCurveLinear; - } - - // NOTE: As of iOS 5 this is only supposed to block interaction events for the views being animated, not the whole app. - if (ignoreInteractionEvents) { - [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; - } - - UIViewBlockAnimationDelegate *delegate = [[UIViewBlockAnimationDelegate alloc] init]; - delegate.completion = completion; - delegate.ignoreInteractionEvents = ignoreInteractionEvents; - - [UIView beginAnimations:nil context:NULL]; - [UIView setAnimationCurve:animationCurve]; - [UIView setAnimationDelay:delay]; - [UIView setAnimationDuration:duration]; - [UIView setAnimationBeginsFromCurrentState:beginFromCurrentState]; - [UIView setAnimationDelegate:delegate]; // this is retained here - [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:)]; - [UIView setAnimationRepeatCount:(repeatAnimation? FLT_MAX : 0)]; - [UIView setAnimationRepeatAutoreverses:autoreverseRepeat]; + [self _beginAnimationsWithOptions:options | UIViewAnimationOptionTransitionNone]; + [self setAnimationDuration:duration]; + [self setAnimationDelay:delay]; + [self _setAnimationCompletionBlock:completion]; animations(); - [UIView commitAnimations]; - [delegate release]; + [self commitAnimations]; } + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion { [self animateWithDuration:duration delay:0 - options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionNone + options:UIViewAnimationOptionCurveEaseInOut animations:animations completion:completion]; } @@ -1029,17 +1038,41 @@ + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void)) [self animateWithDuration:duration animations:animations completion:NULL]; } -+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completio ++ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion { + [self _beginAnimationsWithOptions:options]; + [self setAnimationDuration:duration]; + [self _setAnimationCompletionBlock:completion]; + [self _setAnimationTransitionView:view]; + + if (animations) { + animations(); + } + + [self commitAnimations]; } + (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion { + [self transitionWithView:fromView.superview + duration:duration + options:options + animations:^{ + if (UIViewAnimationOptionIsSet(options, UIViewAnimationOptionShowHideTransitionViews)) { + fromView.hidden = YES; + toView.hidden = NO; + } else { + [fromView.superview addSubview:toView]; + [fromView removeFromSuperview]; + } + } + completion:completion]; } + (void)beginAnimations:(NSString *)animationID context:(void *)context { - [_animationGroups addObject:[UIViewAnimationGroup animationGroupWithName:animationID context:context]]; + [self _beginAnimationsWithOptions:UIViewAnimationCurveEaseInOut]; + [self _setAnimationName:animationID context:context]; } + (void)commitAnimations @@ -1052,52 +1085,74 @@ + (void)commitAnimations + (void)setAnimationBeginsFromCurrentState:(BOOL)beginFromCurrentState { - [[_animationGroups lastObject] setAnimationBeginsFromCurrentState:beginFromCurrentState]; + [[_animationGroups lastObject] setBeginsFromCurrentState:beginFromCurrentState]; } + (void)setAnimationCurve:(UIViewAnimationCurve)curve { - [[_animationGroups lastObject] setAnimationCurve:curve]; + [[_animationGroups lastObject] setCurve:curve]; } + (void)setAnimationDelay:(NSTimeInterval)delay { - [[_animationGroups lastObject] setAnimationDelay:delay]; + [[_animationGroups lastObject] setDelay:delay]; } + (void)setAnimationDelegate:(id)delegate { - [[_animationGroups lastObject] setAnimationDelegate:delegate]; + [[_animationGroups lastObject] setDelegate:delegate]; } + (void)setAnimationDidStopSelector:(SEL)selector { - [[_animationGroups lastObject] setAnimationDidStopSelector:selector]; + [[_animationGroups lastObject] setDidStopSelector:selector]; } + (void)setAnimationDuration:(NSTimeInterval)duration { - [[_animationGroups lastObject] setAnimationDuration:duration]; + [[_animationGroups lastObject] setDuration:duration]; } + (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses { - [[_animationGroups lastObject] setAnimationRepeatAutoreverses:repeatAutoreverses]; + [[_animationGroups lastObject] setRepeatAutoreverses:repeatAutoreverses]; } + (void)setAnimationRepeatCount:(float)repeatCount { - [[_animationGroups lastObject] setAnimationRepeatCount:repeatCount]; + [[_animationGroups lastObject] setRepeatCount:repeatCount]; } + (void)setAnimationWillStartSelector:(SEL)selector { - [[_animationGroups lastObject] setAnimationWillStartSelector:selector]; + [[_animationGroups lastObject] setWillStartSelector:selector]; } + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache { - [[_animationGroups lastObject] setAnimationTransition:transition forView:view cache:cache]; + [self _setAnimationTransitionView:view]; + + switch (transition) { + case UIViewAnimationTransitionNone: + [[_animationGroups lastObject] setTransition:UIViewAnimationGroupTransitionNone]; + break; + + case UIViewAnimationTransitionFlipFromLeft: + [[_animationGroups lastObject] setTransition:UIViewAnimationGroupTransitionFlipFromLeft]; + break; + + case UIViewAnimationTransitionFlipFromRight: + [[_animationGroups lastObject] setTransition:UIViewAnimationGroupTransitionFlipFromRight]; + break; + + case UIViewAnimationTransitionCurlUp: + [[_animationGroups lastObject] setTransition:UIViewAnimationGroupTransitionCurlUp]; + break; + + case UIViewAnimationTransitionCurlDown: + [[_animationGroups lastObject] setTransition:UIViewAnimationGroupTransitionCurlDown]; + break; + } } + (BOOL)areAnimationsEnabled diff --git a/UIKit/Classes/UIViewAdapter.h b/UIKit/Classes/UIViewAdapter.h index 881dfa23..0a3c9c0f 100644 --- a/UIKit/Classes/UIViewAdapter.h +++ b/UIKit/Classes/UIViewAdapter.h @@ -31,14 +31,7 @@ @class NSView, UINSClipView; -@interface UIViewAdapter : UIScrollView { -@private - UINSClipView *_clipView; - NSView *_view; -} - +@interface UIViewAdapter : UIScrollView - (id)initWithNSView:(NSView *)aNSView; - -@property (nonatomic, retain) NSView *NSView; - +@property (nonatomic, strong) NSView *NSView; @end diff --git a/UIKit/Classes/UIViewAdapter.m b/UIKit/Classes/UIViewAdapter.m index 6e05ce87..9525b1b6 100644 --- a/UIKit/Classes/UIViewAdapter.m +++ b/UIKit/Classes/UIViewAdapter.m @@ -42,7 +42,9 @@ #import -@implementation UIViewAdapter +@implementation UIViewAdapter { + UINSClipView *_clipView; +} @synthesize NSView=_view; #pragma mark - @@ -71,9 +73,6 @@ - (id)initWithNSView:(NSView *)aNSView - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIViewHiddenDidChangeNotification object:nil]; - [_view release]; - [_clipView release]; - [super dealloc]; } #pragma mark - @@ -83,7 +82,7 @@ - (void)_addNSView { [_clipView scrollToPoint:NSPointFromCGPoint(self.contentOffset)]; - [[self.window.screen UIKitView] addSubview:_clipView]; + [self.window.screen.UIKitView addSubview:_clipView]; // all of these notifications are hacks to detect when views or superviews of this view move or change in ways that require // the actual NSView to get updated. it's not pretty, but I cannot come up with a better way at this point. @@ -106,15 +105,11 @@ - (void)_removeNSView - (void)_updateLayers { [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue - forKey:kCATransactionDisableActions]; + [CATransaction setAnimationDuration:0]; CALayer *layer = self.layer; 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; - // always make sure it's at the very bottom [layer insertSublayer:clipLayer atIndex:0]; @@ -160,7 +155,7 @@ - (BOOL)_NSViewShouldBeVisible - (void)_updateNSViews { if ([self _NSViewShouldBeVisible]) { - if ([_clipView superview] != [self.window.screen UIKitView]) { + if ([_clipView superview] != self.window.screen.UIKitView) { [self _addNSView]; } @@ -209,8 +204,7 @@ - (void)setNSView:(NSView *)aNSView [self resignFirstResponder]; [self _removeNSView]; - [_view release]; - _view = [aNSView retain]; + _view = aNSView; [_clipView setDocumentView:_view]; [self _updateNSViews]; @@ -257,7 +251,7 @@ - (BOOL)resignFirstResponder const BOOL didResign = [super resignFirstResponder]; if (didResign && [[_view window] firstResponder] == _view) { - [[_view window] makeFirstResponder:[self.window.screen UIKitView]]; + [[_view window] makeFirstResponder:self.window.screen.UIKitView]; } return didResign; diff --git a/UIKit/Classes/UIViewAnimationGroup.h b/UIKit/Classes/UIViewAnimationGroup.h index b9516498..856260db 100644 --- a/UIKit/Classes/UIViewAnimationGroup.h +++ b/UIKit/Classes/UIViewAnimationGroup.h @@ -29,42 +29,42 @@ #import "UIView.h" -@interface UIViewAnimationGroup : NSObject { -@private - NSString *_name; - void *_context; - NSUInteger _waitingAnimations; - BOOL _didSendStartMessage; - NSTimeInterval _animationDelay; - NSTimeInterval _animationDuration; - UIViewAnimationCurve _animationCurve; - id _animationDelegate; - SEL _animationDidStopSelector; - SEL _animationWillStartSelector; - BOOL _animationBeginsFromCurrentState; - BOOL _animationRepeatAutoreverses; - float _animationRepeatCount; - CFTimeInterval _animationBeginTime; - CALayer *_transitionLayer; - UIViewAnimationTransition _transitionType; - BOOL _transitionShouldCache; - NSMutableSet *_animatingViews; -} +typedef NS_ENUM(NSInteger, UIViewAnimationGroupTransition) { + UIViewAnimationGroupTransitionNone, + UIViewAnimationGroupTransitionFlipFromLeft, + UIViewAnimationGroupTransitionFlipFromRight, + UIViewAnimationGroupTransitionCurlUp, + UIViewAnimationGroupTransitionCurlDown, + UIViewAnimationGroupTransitionFlipFromTop, + UIViewAnimationGroupTransitionFlipFromBottom, + UIViewAnimationGroupTransitionCrossDissolve, +}; -+ (id)animationGroupWithName:(NSString *)theName context:(void *)theContext; +extern BOOL UIViewAnimationOptionIsSet(UIViewAnimationOptions options, UIViewAnimationOptions option); + +@interface UIViewAnimationGroup : NSObject + +- (id)initWithAnimationOptions:(UIViewAnimationOptions)options; - (id)actionForView:(UIView *)view forKey:(NSString *)keyPath; +- (void)setTransitionView:(UIView *)view shouldCache:(BOOL)cache; + +- (NSArray *)allAnimatingViews; -- (void)setAnimationBeginsFromCurrentState:(BOOL)beginFromCurrentState; -- (void)setAnimationCurve:(UIViewAnimationCurve)curve; -- (void)setAnimationDelay:(NSTimeInterval)delay; -- (void)setAnimationDelegate:(id)delegate; // retained! (also true of the real UIKit) -- (void)setAnimationDidStopSelector:(SEL)selector; -- (void)setAnimationDuration:(NSTimeInterval)duration; -- (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses; -- (void)setAnimationRepeatCount:(float)repeatCount; -- (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache; -- (void)setAnimationWillStartSelector:(SEL)selector; +@property (nonatomic, copy) NSString *name; +@property (nonatomic, assign) void *context; +@property (nonatomic, copy) void (^completionBlock)(BOOL finished); +@property (nonatomic, assign) BOOL allowUserInteraction; +@property (nonatomic, assign) BOOL beginsFromCurrentState; +@property (nonatomic, assign) UIViewAnimationCurve curve; +@property (nonatomic, assign) NSTimeInterval delay; +@property (nonatomic, strong) id delegate; +@property (nonatomic, assign) SEL didStopSelector; +@property (nonatomic, assign) SEL willStartSelector; +@property (nonatomic, assign) NSTimeInterval duration; +@property (nonatomic, assign) BOOL repeatAutoreverses; +@property (nonatomic, assign) float repeatCount; +@property (nonatomic, assign) UIViewAnimationGroupTransition transition; - (void)commit; diff --git a/UIKit/Classes/UIViewAnimationGroup.m b/UIKit/Classes/UIViewAnimationGroup.m index 01765233..0e1664b5 100644 --- a/UIKit/Classes/UIViewAnimationGroup.m +++ b/UIKit/Classes/UIViewAnimationGroup.m @@ -30,8 +30,11 @@ #import "UIViewAnimationGroup.h" #import #import "UIColor.h" +#import "UIApplication.h" -static CAMediaTimingFunction *CAMediaTimingFunctionFromUIViewAnimationCurve(UIViewAnimationCurve curve) +static NSMutableSet *runningAnimationGroups = nil; + +static inline CAMediaTimingFunction *CAMediaTimingFunctionFromUIViewAnimationCurve(UIViewAnimationCurve curve) { switch (curve) { case UIViewAnimationCurveEaseInOut: return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; @@ -42,106 +45,161 @@ return nil; } -@implementation UIViewAnimationGroup +BOOL UIViewAnimationOptionIsSet(UIViewAnimationOptions options, UIViewAnimationOptions option) +{ + return ((options & option) == option); +} + +static inline UIViewAnimationOptions UIViewAnimationOptionCurve(UIViewAnimationOptions options) +{ + return (options & (UIViewAnimationOptionCurveEaseInOut + | UIViewAnimationOptionCurveEaseIn + | UIViewAnimationOptionCurveEaseOut + | UIViewAnimationOptionCurveLinear)); +} + +static inline UIViewAnimationOptions UIViewAnimationOptionTransition(UIViewAnimationOptions options) +{ + return (options & (UIViewAnimationOptionTransitionNone + | UIViewAnimationOptionTransitionFlipFromLeft + | UIViewAnimationOptionTransitionFlipFromRight + | UIViewAnimationOptionTransitionCurlUp + | UIViewAnimationOptionTransitionCurlDown + | UIViewAnimationOptionTransitionCrossDissolve + | UIViewAnimationOptionTransitionFlipFromTop + | UIViewAnimationOptionTransitionFlipFromBottom)); +} + +@implementation UIViewAnimationGroup { + NSUInteger _waitingAnimations; + BOOL _didStart; + CFTimeInterval _animationBeginTime; + UIView *_transitionView; + BOOL _transitionShouldCache; + NSMutableSet *_animatingViews; +} + ++ (void)initialize +{ + if (self == [UIViewAnimationGroup class]) { + runningAnimationGroups = [NSMutableSet setWithCapacity:1]; + } +} -- (id)initWithGroupName:(NSString *)theName context:(void *)theContext +- (id)initWithAnimationOptions:(UIViewAnimationOptions)options { if ((self=[super init])) { - _name = [theName copy]; - _context = theContext; _waitingAnimations = 1; - _animationDuration = 0.2; - _animationCurve = UIViewAnimationCurveEaseInOut; - _animationBeginsFromCurrentState = NO; - _animationRepeatAutoreverses = NO; - _animationRepeatCount = 0; _animationBeginTime = CACurrentMediaTime(); - _animatingViews = [[NSMutableSet alloc] initWithCapacity:0]; + _animatingViews = [NSMutableSet setWithCapacity:2]; + + self.duration = 0.2; + + self.repeatCount = UIViewAnimationOptionIsSet(options, UIViewAnimationOptionRepeat)? FLT_MAX : 0; + self.allowUserInteraction = UIViewAnimationOptionIsSet(options, UIViewAnimationOptionAllowUserInteraction); + self.repeatAutoreverses = UIViewAnimationOptionIsSet(options, UIViewAnimationOptionAutoreverse); + self.beginsFromCurrentState = UIViewAnimationOptionIsSet(options, UIViewAnimationOptionBeginFromCurrentState); + + const UIViewAnimationOptions animationCurve = UIViewAnimationOptionCurve(options); + if (animationCurve == UIViewAnimationOptionCurveEaseIn) { + self.curve = UIViewAnimationCurveEaseIn; + } else if (animationCurve == UIViewAnimationOptionCurveEaseOut) { + self.curve = UIViewAnimationCurveEaseOut; + } else if (animationCurve == UIViewAnimationOptionCurveLinear) { + self.curve = UIViewAnimationCurveLinear; + } else { + self.curve = UIViewAnimationCurveEaseInOut; + } + + const UIViewAnimationOptions animationTransition = UIViewAnimationOptionTransition(options); + if (animationTransition == UIViewAnimationOptionTransitionFlipFromLeft) { + self.transition = UIViewAnimationGroupTransitionFlipFromLeft; + } else if (animationTransition == UIViewAnimationOptionTransitionFlipFromRight) { + self.transition = UIViewAnimationGroupTransitionFlipFromRight; + } else if (animationTransition == UIViewAnimationOptionTransitionCurlUp) { + self.transition = UIViewAnimationGroupTransitionCurlUp; + } else if (animationTransition == UIViewAnimationOptionTransitionCurlDown) { + self.transition = UIViewAnimationGroupTransitionCurlDown; + } else if (animationTransition == UIViewAnimationOptionTransitionCrossDissolve) { + self.transition = UIViewAnimationGroupTransitionCrossDissolve; + } else if (animationTransition == UIViewAnimationOptionTransitionFlipFromTop) { + self.transition = UIViewAnimationGroupTransitionFlipFromTop; + } else if (animationTransition == UIViewAnimationOptionTransitionFlipFromBottom) { + self.transition = UIViewAnimationGroupTransitionFlipFromBottom; + } else { + self.transition = UIViewAnimationGroupTransitionNone; + } } return self; } -- (void)dealloc +- (NSArray *)allAnimatingViews { - [_name release]; - [_animationDelegate release]; - [_animatingViews release]; - [super dealloc]; + @synchronized(runningAnimationGroups) { + return [_animatingViews allObjects]; + } } -+ (id)animationGroupWithName:(NSString *)theName context:(void *)theContext +- (void)notifyAnimationsDidStartIfNeeded { - return [[[self alloc] initWithGroupName:theName context:theContext] autorelease]; + if (!_didStart) { + _didStart = YES; + + @synchronized(runningAnimationGroups) { + [runningAnimationGroups addObject:self]; + } + + if ([self.delegate respondsToSelector:self.willStartSelector]) { + typedef void(*WillStartMethod)(id, SEL, NSString *, void *); + WillStartMethod method = (WillStartMethod)[self.delegate methodForSelector:self.willStartSelector]; + method(self.delegate, self.willStartSelector, self.name, self.context); + } + } } - (void)notifyAnimationsDidStopIfNeededUsingStatus:(BOOL)animationsDidFinish { if (_waitingAnimations == 0) { - if ([_animationDelegate respondsToSelector:_animationDidStopSelector]) { - NSMethodSignature *signature = [_animationDelegate methodSignatureForSelector:_animationDidStopSelector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:_animationDidStopSelector]; - NSInteger remaining = [signature numberOfArguments] - 2; - + if ([self.delegate respondsToSelector:self.didStopSelector]) { NSNumber *finishedArgument = [NSNumber numberWithBool:animationsDidFinish]; - - if (remaining > 0) { - [invocation setArgument:&_name atIndex:2]; - remaining--; - } - - if (remaining > 0) { - [invocation setArgument:&finishedArgument atIndex:3]; - remaining--; - } - - if (remaining > 0) { - [invocation setArgument:&_context atIndex:4]; - } - - [invocation invokeWithTarget:_animationDelegate]; + typedef void(*DidFinishMethod)(id, SEL, NSString *, NSNumber *, void *); + DidFinishMethod method = (DidFinishMethod)[self.delegate methodForSelector:self.didStopSelector]; + method(self.delegate, self.didStopSelector, self.name, finishedArgument, self.context); + } + + if (self.completionBlock) { + self.completionBlock(animationsDidFinish); + } + + @synchronized(runningAnimationGroups) { + [_animatingViews removeAllObjects]; + [runningAnimationGroups removeObject:self]; } - [_animatingViews removeAllObjects]; } } - (void)animationDidStart:(CAAnimation *)theAnimation { - if (!_didSendStartMessage) { - if ([_animationDelegate respondsToSelector:_animationWillStartSelector]) { - NSMethodSignature *signature = [_animationDelegate methodSignatureForSelector:_animationWillStartSelector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setSelector:_animationWillStartSelector]; - NSInteger remaining = [signature numberOfArguments] - 2; - - if (remaining > 0) { - [invocation setArgument:&_name atIndex:2]; - remaining--; - } - - if (remaining > 0) { - [invocation setArgument:&_context atIndex:3]; - } - - [invocation invokeWithTarget:_animationDelegate]; - } - _didSendStartMessage = YES; - } + NSAssert([NSThread isMainThread], @"expecting this to be on the main thread"); + + [self notifyAnimationsDidStartIfNeeded]; } - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { + NSAssert([NSThread isMainThread], @"expecting this to be on the main thread"); + _waitingAnimations--; [self notifyAnimationsDidStopIfNeededUsingStatus:flag]; } - (CAAnimation *)addAnimation:(CAAnimation *)animation { - animation.timingFunction = CAMediaTimingFunctionFromUIViewAnimationCurve(_animationCurve); - animation.duration = _animationDuration; - animation.beginTime = _animationBeginTime + _animationDelay; - animation.repeatCount = _animationRepeatCount; - animation.autoreverses = _animationRepeatAutoreverses; + animation.timingFunction = CAMediaTimingFunctionFromUIViewAnimationCurve(self.curve); + animation.duration = self.duration; + animation.beginTime = _animationBeginTime + self.delay; + animation.repeatCount = self.repeatCount; + animation.autoreverses = self.repeatAutoreverses; animation.fillMode = kCAFillModeBackwards; animation.delegate = self; animation.removedOnCompletion = YES; @@ -151,83 +209,70 @@ - (CAAnimation *)addAnimation:(CAAnimation *)animation - (id)actionForView:(UIView *)view forKey:(NSString *)keyPath { - [_animatingViews addObject:view]; - CALayer *layer = view.layer; - CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath]; - animation.fromValue = _animationBeginsFromCurrentState? [layer.presentationLayer valueForKey:keyPath] : [layer valueForKey:keyPath]; - return [self addAnimation:animation]; -} - -- (void)setAnimationBeginsFromCurrentState:(BOOL)beginFromCurrentState -{ - _animationBeginsFromCurrentState = beginFromCurrentState; -} - -- (void)setAnimationCurve:(UIViewAnimationCurve)curve -{ - _animationCurve = curve; -} - -- (void)setAnimationDelay:(NSTimeInterval)delay -{ - _animationDelay = delay; -} - -- (void)setAnimationDelegate:(id)delegate -{ - if (delegate != _animationDelegate) { - [_animationDelegate release]; - _animationDelegate = [delegate retain]; + @synchronized(runningAnimationGroups) { + [_animatingViews addObject:view]; } -} -- (void)setAnimationDidStopSelector:(SEL)selector -{ - _animationDidStopSelector = selector; -} - -- (void)setAnimationDuration:(NSTimeInterval)newDuration -{ - _animationDuration = newDuration; -} - -- (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses -{ - _animationRepeatAutoreverses = repeatAutoreverses; -} - -- (void)setAnimationRepeatCount:(float)repeatCount -{ - _animationRepeatCount = repeatCount; + if (_transitionView && self.transition != UIViewAnimationGroupTransitionNone) { + return nil; + } else { + CALayer *layer = view.layer; + CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath]; + animation.fromValue = self.beginsFromCurrentState? [layer.presentationLayer valueForKey:keyPath] : [layer valueForKey:keyPath]; + return [self addAnimation:animation]; + } } -- (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache +- (void)setTransitionView:(UIView *)view shouldCache:(BOOL)cache; { - _transitionLayer = view.layer; - _transitionType = transition; + _transitionView = view; _transitionShouldCache = cache; } -- (void)setAnimationWillStartSelector:(SEL)selector -{ - _animationWillStartSelector = selector; -} - - (void)commit { - if (_transitionLayer) { + if (_transitionView && self.transition != UIViewAnimationGroupTransitionNone) { CATransition *trans = [CATransition animation]; - trans.type = kCATransitionMoveIn; - switch (_transitionType) { - case UIViewAnimationTransitionNone: trans.subtype = nil; break; - case UIViewAnimationTransitionCurlUp: trans.subtype = kCATransitionFromTop; break; - case UIViewAnimationTransitionCurlDown: trans.subtype = kCATransitionFromBottom; break; - case UIViewAnimationTransitionFlipFromLeft: trans.subtype = kCATransitionFromLeft; break; - case UIViewAnimationTransitionFlipFromRight: trans.subtype = kCATransitionFromRight; break; + switch (self.transition) { + case UIViewAnimationGroupTransitionFlipFromLeft: + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromLeft; + break; + + case UIViewAnimationGroupTransitionFlipFromRight: + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromRight; + break; + + case UIViewAnimationGroupTransitionFlipFromTop: + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromTop; + break; + + case UIViewAnimationGroupTransitionFlipFromBottom: + trans.type = kCATransitionPush; + trans.subtype = kCATransitionFromBottom; + break; + + case UIViewAnimationGroupTransitionCurlUp: + trans.type = kCATransitionReveal; + trans.subtype = kCATransitionFromTop; + break; + + case UIViewAnimationGroupTransitionCurlDown: + trans.type = kCATransitionReveal; + trans.subtype = kCATransitionFromBottom; + break; + + case UIViewAnimationGroupTransitionCrossDissolve: + default: + trans.type = kCATransitionFade; + break; } - [_transitionLayer addAnimation:[self addAnimation:trans] forKey:kCATransition]; + [_animatingViews addObject:_transitionView]; + [_transitionView.layer addAnimation:[self addAnimation:trans] forKey:kCATransition]; } _waitingAnimations--; diff --git a/UIKit/Classes/UIViewController.h b/UIKit/Classes/UIViewController.h index 87796790..d0fbb7f1 100644 --- a/UIKit/Classes/UIViewController.h +++ b/UIKit/Classes/UIViewController.h @@ -34,43 +34,23 @@ @class UITabBarController; -typedef enum { +typedef NS_ENUM(NSInteger, UIModalPresentationStyle) { UIModalPresentationFullScreen = 0, UIModalPresentationPageSheet, UIModalPresentationFormSheet, UIModalPresentationCurrentContext, -} UIModalPresentationStyle; +}; -typedef enum { +typedef NS_ENUM(NSInteger, UIModalTransitionStyle) { UIModalTransitionStyleCoverVertical = 0, UIModalTransitionStyleFlipHorizontal, UIModalTransitionStyleCrossDissolve, UIModalTransitionStylePartialCurl, -} UIModalTransitionStyle; +}; @class UINavigationItem, UINavigationController, UIBarButtonItem, UISplitViewController; -@interface UIViewController : UIResponder { -@private - UIView *_view; - BOOL _wantsFullScreenLayout; - NSString *_title; - CGSize _contentSizeForViewInPopover; - BOOL _modalInPopover; - UINavigationItem *_navigationItem; - NSArray *_toolbarItems; - UIModalPresentationStyle _modalPresentationStyle; - BOOL _editing; - BOOL _hidesBottomBarWhenPushed; - UIViewController *_parentViewController; - UIViewController *_modalViewController; - UISearchDisplayController *_searchDisplayController; - UIModalTransitionStyle _modalTransitionStyle; - - UITabBarItem *_tabBarItem; - UITabBarController *_tabBarController; -} - +@interface UIViewController : UIResponder - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle; // won't load a nib no matter what you do! - (BOOL)isViewLoaded; @@ -86,46 +66,70 @@ typedef enum { - (void)viewWillLayoutSubviews; - (void)viewDidLayoutSubviews; +- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion; +- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion; + +// these are deprecated on iOS 6 - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated; // works, but not exactly correctly. - (void)dismissModalViewControllerAnimated:(BOOL)animated; // see comments in dismissModalViewController -- (void)didReceiveMemoryWarning; // doesn't do anything and is never called... +- (void)didReceiveMemoryWarning; // is called when UIApplicationDidReceiveMemoryWarningNotification is posted, which is currently only done by private API for.. fun, I guess? - (void)setToolbarItems:(NSArray *)toolbarItems animated:(BOOL)animated; - (void)setEditing:(BOOL)editing animated:(BOOL)animated; -- (UIBarButtonItem *)editButtonItem; // not implemented +- (UIBarButtonItem *)editButtonItem; - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration; - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation; +- (BOOL)isMovingFromParentViewController; +- (BOOL)isMovingToParentViewController; +- (BOOL)isBeingPresented; +- (BOOL)isBeingDismissed; + +- (void)addChildViewController:(UIViewController *)childController; +- (void)removeFromParentViewController; +- (BOOL)shouldAutomaticallyForwardRotationMethods; +- (BOOL)shouldAutomaticallyForwardAppearanceMethods; +- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion; +- (void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated; // iOS 6+ +- (void)endAppearanceTransition; // iOS 6+ -@property (nonatomic, readonly, copy) NSString *nibName; // always returns nil -@property (nonatomic, readonly, retain) NSBundle *nibBundle; // always returns nil +- (void)willMoveToParentViewController:(UIViewController *)parent; +- (void)didMoveToParentViewController:(UIViewController *)parent; + +@property (nonatomic, readonly, copy) NSString *nibName; +@property (nonatomic, readonly, retain) NSBundle *nibBundle; @property (nonatomic, retain) UIView *view; -@property (nonatomic, assign) BOOL wantsFullScreenLayout; // doesn't do anything right now +@property (nonatomic, assign) BOOL wantsFullScreenLayout; @property (nonatomic, copy) NSString *title; -@property (nonatomic, readonly) UIInterfaceOrientation interfaceOrientation; // always returns UIInterfaceOrientationLandscapeLeft +@property (nonatomic, readonly) UIInterfaceOrientation interfaceOrientation; @property (nonatomic, readonly, retain) UINavigationItem *navigationItem; @property (nonatomic, retain) NSArray *toolbarItems; @property (nonatomic, getter=isEditing) BOOL editing; @property (nonatomic) BOOL hidesBottomBarWhenPushed; @property (nonatomic, readwrite) CGSize contentSizeForViewInPopover; -@property (nonatomic,readwrite,getter=isModalInPopover) BOOL modalInPopover; +@property (nonatomic, readwrite, getter=isModalInPopover) BOOL modalInPopover; -@property (nonatomic, readonly) UIViewController *modalViewController; @property (nonatomic, assign) UIModalPresentationStyle modalPresentationStyle; -@property (nonatomic, assign) UIModalTransitionStyle modalTransitionStyle; // not used right now +@property (nonatomic, assign) UIModalTransitionStyle modalTransitionStyle; +@property (nonatomic, assign) BOOL definesPresentationContext; +@property (nonatomic, assign) BOOL providesPresentationContextTransitionStyle; @property (nonatomic, readonly) UIViewController *parentViewController; + +@property (nonatomic, readonly) NSArray *childViewControllers; +@property (nonatomic, readonly) UIViewController *presentingViewController; +@property (nonatomic, readonly) UIViewController *presentedViewController; + @property (nonatomic, readonly, retain) UINavigationController *navigationController; @property (nonatomic, readonly, retain) UISplitViewController *splitViewController; -@property (nonatomic, readonly, retain) UISearchDisplayController *searchDisplayController; // stub - -// stubs -@property (nonatomic, retain) UITabBarItem *tabBarItem; @property (nonatomic, readonly, retain) UITabBarController *tabBarController; +@property (nonatomic, readonly, retain) UISearchDisplayController *searchDisplayController; +@property (nonatomic, readonly, retain) UIViewController *modalViewController; +@property (nonatomic, retain) UITabBarItem *tabBarItem; @end diff --git a/UIKit/Classes/UIViewController.m b/UIKit/Classes/UIViewController.m index 6d0ec441..89e09b5a 100644 --- a/UIKit/Classes/UIViewController.m +++ b/UIKit/Classes/UIViewController.m @@ -27,7 +27,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIViewController.h" +#import "UIViewControllerAppKitIntegration.h" #import "UIView+UIPrivate.h" #import "UIScreen.h" #import "UIWindow.h" @@ -40,12 +40,23 @@ #import "UIScreen.h" #import "UITabBarController.h" -@implementation UIViewController -@synthesize view=_view, wantsFullScreenLayout=_wantsFullScreenLayout, title=_title, contentSizeForViewInPopover=_contentSizeForViewInPopover; -@synthesize modalInPopover=_modalInPopover, toolbarItems=_toolbarItems, modalPresentationStyle=_modalPresentationStyle, editing=_editing; -@synthesize modalViewController=_modalViewController, parentViewController=_parentViewController; -@synthesize modalTransitionStyle=_modalTransitionStyle, hidesBottomBarWhenPushed=_hidesBottomBarWhenPushed; -@synthesize searchDisplayController=_searchDisplayController, tabBarItem=_tabBarItem, tabBarController=_tabBarController; +typedef NS_ENUM(NSInteger, _UIViewControllerParentageTransition) { + _UIViewControllerParentageTransitionNone = 0, + _UIViewControllerParentageTransitionToParent, + _UIViewControllerParentageTransitionFromParent, +}; + +@implementation UIViewController { + UIView *_view; + UINavigationItem *_navigationItem; + NSMutableArray *_childViewControllers; + __unsafe_unretained UIViewController *_parentViewController; + + NSUInteger _appearanceTransitionStack; + BOOL _appearanceTransitionIsAnimated; + BOOL _viewIsAppearing; + _UIViewControllerParentageTransition _parentageTransition; +} - (id)init { @@ -57,18 +68,15 @@ - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle if ((self=[super init])) { _contentSizeForViewInPopover = CGSizeMake(320,1100); _hidesBottomBarWhenPushed = NO; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:[UIApplication sharedApplication]]; } return self; } - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:[UIApplication sharedApplication]]; [_view _setViewController:nil]; - [_modalViewController release]; - [_navigationItem release]; - [_title release]; - [_view release]; - [super dealloc]; } - (NSString *)nibName @@ -86,6 +94,16 @@ - (UIResponder *)nextResponder return _view.superview; } +- (UIViewController *)defaultResponderChildViewController +{ + return nil; +} + +- (UIResponder *)defaultResponder +{ + return nil; +} + - (BOOL)isViewLoaded { return (_view != nil); @@ -96,8 +114,11 @@ - (UIView *)view if ([self isViewLoaded]) { return _view; } else { + const BOOL wereEnabled = [UIView areAnimationsEnabled]; + [UIView setAnimationsEnabled:NO]; [self loadView]; [self viewDidLoad]; + [UIView setAnimationsEnabled:wereEnabled]; return _view; } } @@ -106,15 +127,14 @@ - (void)setView:(UIView *)aView { if (aView != _view) { [_view _setViewController:nil]; - [_view release]; - _view = [aView retain]; + _view = aView; [_view _setViewController:self]; } } - (void)loadView { - self.view = [[[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)] autorelease]; + self.view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)]; } - (void)viewDidLoad @@ -166,16 +186,18 @@ - (UINavigationItem *)navigationItem return _navigationItem; } -- (void)_setParentViewController:(UIViewController *)parentController +- (void)setTitle:(NSString *)title { - _parentViewController = parentController; + if (![_title isEqual:title]) { + _title = [title copy]; + _navigationItem.title = _title; + } } - (void)setToolbarItems:(NSArray *)theToolbarItems animated:(BOOL)animated { - if (_toolbarItems != theToolbarItems) { - [_toolbarItems release]; - _toolbarItems = [theToolbarItems retain]; + if (![_toolbarItems isEqual:theToolbarItems]) { + _toolbarItems = theToolbarItems; [self.navigationController.toolbar setItems:_toolbarItems animated:animated]; } } @@ -201,10 +223,19 @@ - (UIBarButtonItem *)editButtonItem return nil; } +- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion +{ +} + +- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion +{ +} + - (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated { + /* if (!_modalViewController && _modalViewController != self) { - _modalViewController = [modalViewController retain]; + _modalViewController = modalViewController; [_modalViewController _setParentViewController:self]; UIWindow *window = self.view.window; @@ -221,13 +252,14 @@ - (void)presentModalViewController:(UIViewController *)modalViewController anima selfView.hidden = YES; // I think the real one may actually remove it, which would mean needing to remember the superview, I guess? Not sure... [self viewDidDisappear:animated]; - [_modalViewController viewDidAppear:animated]; } + */ } - (void)dismissModalViewControllerAnimated:(BOOL)animated { + /* // NOTE: This is not implemented entirely correctly - the actual dismissModalViewController is somewhat subtle. // There is supposed to be a stack of modal view controllers that dismiss in a specific way,e tc. // The whole system of related view controllers is not really right - not just with modals, but everything else like @@ -246,13 +278,13 @@ - (void)dismissModalViewControllerAnimated:(BOOL)animated [_modalViewController.view removeFromSuperview]; [_modalViewController _setParentViewController:nil]; - [_modalViewController autorelease]; _modalViewController = nil; [self viewDidAppear:animated]; } else { [self.parentViewController dismissModalViewControllerAnimated:animated]; } + */ } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation @@ -298,4 +330,202 @@ - (NSString *)description return [NSString stringWithFormat:@"<%@: %p; title = %@; view = %@>", [self className], self, self.title, self.view]; } + + + + + +- (BOOL)isMovingFromParentViewController +{ + // Docs don't say anything about being required to call super for -willMoveToParentViewController: and people + // on StackOverflow seem to tell each other they can override the method without calling super. Based on that, + // I have no freakin' idea how this method here is meant to know when to return YES... + + // I'm inclined to think that the docs are just unclear and that -willMoveToParentViewController: and + // -didMoveToParentViewController: must have to do *something* for this to work without ambiguity. + + // Now that I think about it some more, I suspect that it is far better to assume the docs imply you must call + // super when you override a method *unless* it says not to. If that assumption is sound, then in that case it + // suggests that when overriding -willMoveToParentViewController: and -didMoveToParentViewController: you are + // expected to call super anyway, which means I could put some implementation in the base class versions safely. + // Generally docs do tend to say things like, "parent implementation does nothing" when they mean you can skip + // the call to super, and the docs currently say no such thing for -will/didMoveToParentViewController:. + + // In all likely hood, all that would happen if you didn't call super from a -will/didMoveToParentViewController: + // override is that -isMovingFromParentViewController and -isMovingToParentViewController would return the + // wrong answer, and if you never use them, you'll never even notice that bug! + + return (_appearanceTransitionStack > 0) && (_parentageTransition == _UIViewControllerParentageTransitionFromParent); +} + +- (BOOL)isMovingToParentViewController +{ + return (_appearanceTransitionStack > 0) && (_parentageTransition == _UIViewControllerParentageTransitionToParent); +} + +- (BOOL)isBeingPresented +{ + // TODO + return (_appearanceTransitionStack > 0) && (NO); +} + +- (BOOL)isBeingDismissed +{ + // TODO + return (_appearanceTransitionStack > 0) && (NO); +} + +- (UIViewController *)presentingViewController +{ + // TODO + return nil; +} + +- (UIViewController *)presentedViewController +{ + // TODO + return nil; +} + +- (NSArray *)childViewControllers +{ + return [_childViewControllers copy]; +} + +- (void)addChildViewController:(UIViewController *)childController +{ + NSAssert(childController != nil, @"cannot add nil child view controller"); + NSAssert(childController.parentViewController == nil, @"thou shalt have no other parent before me"); + + if (!_childViewControllers) { + _childViewControllers = [NSMutableArray arrayWithCapacity:1]; + } + + [childController willMoveToParentViewController:self]; + [_childViewControllers addObject:childController]; + childController->_parentViewController = self; +} + +- (void)_removeFromParentViewController +{ + if (_parentViewController) { + [_parentViewController->_childViewControllers removeObject:self]; + + if ([_parentViewController->_childViewControllers count] == 0) { + _parentViewController->_childViewControllers = nil; + } + + _parentViewController = nil; + } +} + +- (void)removeFromParentViewController +{ + NSAssert(self.parentViewController != nil, @"view controller has no parent"); + + [self _removeFromParentViewController]; + [self didMoveToParentViewController:nil]; +} + +- (BOOL)shouldAutomaticallyForwardRotationMethods +{ + return YES; +} + +- (BOOL)shouldAutomaticallyForwardAppearanceMethods +{ + return YES; +} + +- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion +{ + NSAssert(fromViewController.parentViewController == toViewController.parentViewController && fromViewController.parentViewController != nil, @"child controllers must share common parent"); + const BOOL animated = (duration > 0); + + [fromViewController beginAppearanceTransition:NO animated:animated]; + [toViewController beginAppearanceTransition:YES animated:animated]; + + [UIView transitionWithView:self.view + duration:duration + options:options + animations:^{ + if (animations) { + animations(); + } + + [self.view addSubview:toViewController.view]; + } + completion:^(BOOL finished) { + if (completion) { + completion(finished); + } + + [fromViewController.view removeFromSuperview]; + + [fromViewController endAppearanceTransition]; + [toViewController endAppearanceTransition]; + }]; +} + +- (void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated +{ + if (_appearanceTransitionStack == 0 || (_appearanceTransitionStack > 0 && _viewIsAppearing != isAppearing)) { + _appearanceTransitionStack = 1; + _appearanceTransitionIsAnimated = animated; + _viewIsAppearing = isAppearing; + + if ([self shouldAutomaticallyForwardAppearanceMethods]) { + for (UIViewController *child in self.childViewControllers) { + if ([child isViewLoaded] && [child.view isDescendantOfView:self.view]) { + [child beginAppearanceTransition:isAppearing animated:animated]; + } + } + } + + if (_viewIsAppearing) { + [self view]; // ensures the view is loaded before viewWillAppear: happens + [self viewWillAppear:_appearanceTransitionIsAnimated]; + } else { + [self viewWillDisappear:_appearanceTransitionIsAnimated]; + } + } else { + _appearanceTransitionStack++; + } +} + +- (void)endAppearanceTransition +{ + if (_appearanceTransitionStack > 0) { + _appearanceTransitionStack--; + + if (_appearanceTransitionStack == 0) { + if ([self shouldAutomaticallyForwardAppearanceMethods]) { + for (UIViewController *child in self.childViewControllers) { + [child endAppearanceTransition]; + } + } + + if (_viewIsAppearing) { + [self viewDidAppear:_appearanceTransitionIsAnimated]; + } else { + [self viewDidDisappear:_appearanceTransitionIsAnimated]; + } + } + } +} + +- (void)willMoveToParentViewController:(UIViewController *)parent +{ + if (parent) { + _parentageTransition = _UIViewControllerParentageTransitionToParent; + } else { + _parentageTransition = _UIViewControllerParentageTransitionFromParent; + } +} + +- (void)didMoveToParentViewController:(UIViewController *)parent +{ + _parentageTransition = _UIViewControllerParentageTransitionNone; +} + @end diff --git a/UIKit/Classes/UIViewControllerAppKitIntegration.h b/UIKit/Classes/UIViewControllerAppKitIntegration.h new file mode 100644 index 00000000..e54dea47 --- /dev/null +++ b/UIKit/Classes/UIViewControllerAppKitIntegration.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013, 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. + */ + +#import "UIViewController.h" + +@interface UIViewController (AppKitIntegration) +// the purpose of this is to more easily support menu actions so the responder chain isn't +// broken all the time and you don't have to add a bunch of -canBecomeFirstResponser and +// -becomeFirstResponder calls in your code just to be able to handle this situation. On OSX +// it's pretty normal to expect that where you click becomes a responder and gets focus, but +// iOS code doesn't typically have such a notion because being a first responder is almost +// always only used for text fields and such. so iOS code will typically resign the first +// responder and leave nothing in it's place, which is perfectly fine most of the time on iOS. +// however on OSX we want to be able to easily handle menu actions that might apply to a whole +// view or something and since Chameleon bridges the responder chains, this is generally easy +// except that there is almost never a first responder to start sending things to! so the idea +// here is that your custom UIViewController subclasses can override these and return whatever +// they want to help things along. + +// since -defaultResponderChildViewController returns nil by default, you will have to manage +// this yourself everywhere along your view controller hierarchy which is sort of annoying, but +// we used a lot of custom child view controllers in our hierarchy, so it is easy to return +// the most logical "primary" child controller for the user at the time, if there is one, or +// nil if reciever is the most logical place to start. you do not need to recursively call +// -defaultResponderChildViewController, instead just return the best controller from the point +// of view of the receiver and Chameleon will walk down the resulting chain until it returns +// nil. when it eventually returns nil, the search stops and then the last receiver is sent +// -defaultResponder to ask for the responder it would like to use to start the chain. if that +// returns nil, then there is effectively no responder chain so the action just gets passed into +// AppKit's responder chain. if there is a responder, we try to deliver the action down the +// responder chain starting from the result of -defaultResponder. if that fails, we fall off the +// end and end up back on AppKit's chain. + +// -defaultResponderChildViewController is first called on the keyWindow's -rootViewController, +// and only if that window doesn't already have an explicit firstResponder (such as if a control +// or something became first responder in the usual way). it then proceeds as described above +// looking for something to use as the start of a responder chain. + +// returns nil by default +- (UIViewController *)defaultResponderChildViewController; + +// returns nil by default +- (UIResponder *)defaultResponder; +@end diff --git a/UIKit/Classes/UIWebView.h b/UIKit/Classes/UIWebView.h index 768934f7..2bf247af 100644 --- a/UIKit/Classes/UIWebView.h +++ b/UIKit/Classes/UIWebView.h @@ -27,10 +27,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import "UIView.h" +#import "UIScrollView.h" #import "UIDataDetectors.h" -enum { +typedef NS_ENUM(NSInteger, UIWebViewNavigationType) { UIWebViewNavigationTypeLinkClicked, UIWebViewNavigationTypeFormSubmitted, UIWebViewNavigationTypeBackForward, @@ -38,9 +38,8 @@ enum { UIWebViewNavigationTypeFormResubmitted, UIWebViewNavigationTypeOther }; -typedef NSUInteger UIWebViewNavigationType; -@class UIWebView, UIViewAdapter, WebView; +@class UIWebView; @protocol UIWebViewDelegate @optional @@ -49,22 +48,7 @@ typedef NSUInteger UIWebViewNavigationType; - (void)webViewDidFinishLoad:(UIWebView *)webView; @end -@interface UIWebView : UIView { -@private - __unsafe_unretained id _delegate; - NSURLRequest *_request; - UIDataDetectorTypes _dataDetectorTypes; - WebView *_webView; - UIViewAdapter *_webViewAdapter; - BOOL _scalesPageToFit; - - struct { - unsigned shouldStartLoadWithRequest : 1; - unsigned didFailLoadWithError : 1; - unsigned didFinishLoad : 1; - } _delegateHas; -} - +@interface UIWebView : UIView - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL; - (void)loadRequest:(NSURLRequest *)request; - (void)stopLoading; @@ -79,7 +63,7 @@ typedef NSUInteger UIWebViewNavigationType; @property (nonatomic, readonly, getter=canGoBack) BOOL canGoBack; @property (nonatomic, readonly, getter=canGoForward) BOOL canGoForward; @property (nonatomic, assign) BOOL scalesPageToFit; // not implemented -@property (nonatomic, readonly, retain) NSURLRequest *request; +@property (nonatomic, readonly, strong) NSURLRequest *request; @property (nonatomic) UIDataDetectorTypes dataDetectorTypes; - +@property (nonatomic, readonly, strong) UIScrollView *scrollView; // not implemented @end diff --git a/UIKit/Classes/UIWebView.m b/UIKit/Classes/UIWebView.m index df9da91c..261f16ae 100644 --- a/UIKit/Classes/UIWebView.m +++ b/UIKit/Classes/UIWebView.m @@ -31,14 +31,20 @@ #import "UIViewAdapter.h" #import -@implementation UIWebView -@synthesize request=_request, delegate=_delegate, dataDetectorTypes=_dataDetectorTypes, scalesPageToFit=_scalesPageToFit; +@implementation UIWebView { + WebView *_webView; + UIViewAdapter *_webViewAdapter; + + struct { + unsigned shouldStartLoadWithRequest : 1; + unsigned didFailLoadWithError : 1; + unsigned didFinishLoad : 1; + } _delegateHas; +} - (id)initWithFrame:(CGRect)frame { if ((self=[super initWithFrame:frame])) { - _scalesPageToFit = NO; - _webView = [(WebView *)[WebView alloc] initWithFrame:NSRectFromCGRect(self.bounds)]; [_webView setAutoresizingMask:(NSViewWidthSizable|NSViewHeightSizable)]; [_webView setPolicyDelegate:self]; @@ -60,9 +66,6 @@ - (void)dealloc [_webView setPolicyDelegate:nil]; [_webView setFrameLoadDelegate:nil]; [_webView setUIDelegate:nil]; - [_webViewAdapter release]; - [_webView release]; - [super dealloc]; } - (void)layoutSubviews @@ -87,8 +90,7 @@ - (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL - (void)loadRequest:(NSURLRequest *)request { if (request != _request) { - [_request release]; - _request = [request retain]; + _request = request; } [[_webView mainFrame] loadRequest:_request]; @@ -150,6 +152,11 @@ - (id)valueForUndefinedKey:(NSString *)key return nil; } +- (UIScrollView *)scrollView +{ + return nil; +} + #pragma mark - #pragma mark WebView Policy Delegate diff --git a/UIKit/Classes/UIWindow.h b/UIKit/Classes/UIWindow.h index dda30d6a..d3ea7300 100644 --- a/UIKit/Classes/UIWindow.h +++ b/UIKit/Classes/UIWindow.h @@ -43,6 +43,7 @@ extern NSString *const UIKeyboardWillShowNotification; extern NSString *const UIKeyboardDidShowNotification; extern NSString *const UIKeyboardWillHideNotification; extern NSString *const UIKeyboardDidHideNotification; +extern NSString *const UIKeyboardWillChangeFrameNotification; extern NSString *const UIKeyboardFrameBeginUserInfoKey; extern NSString *const UIKeyboardFrameEndUserInfoKey; @@ -54,17 +55,9 @@ extern NSString *const UIKeyboardCenterBeginUserInfoKey; extern NSString *const UIKeyboardCenterEndUserInfoKey; extern NSString *const UIKeyboardBoundsUserInfoKey; - @class UIScreen, UIViewController; -@interface UIWindow : UIView { -@private - UIScreen *_screen; - UIResponder *_firstResponder; - NSUndoManager *_undoManager; - UIViewController *_rootViewController; -} - +@interface UIWindow : UIView - (CGPoint)convertPoint:(CGPoint)toConvert toWindow:(UIWindow *)toWindow; - (CGPoint)convertPoint:(CGPoint)toConvert fromWindow:(UIWindow *)fromWindow; - (CGRect)convertRect:(CGRect)toConvert fromWindow:(UIWindow *)fromWindow; @@ -72,13 +65,20 @@ extern NSString *const UIKeyboardBoundsUserInfoKey; - (void)makeKeyWindow; - (void)makeKeyAndVisible; + - (void)resignKeyWindow; - (void)becomeKeyWindow; + - (void)sendEvent:(UIEvent *)event; +// this property returns YES only if the underlying screen's UIKitView is on the AppKit's key window +// and this UIWindow was made key at some point in the past (and is still key from the point of view +// of the underlying screen) which is of course rather different from the real UIKit. +// this is done because unlike iOS, on OSX the user can change the key window at will at any time and +// we need a way to reconnect key windows when they change. :/ @property (nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow; -@property (nonatomic, retain) UIScreen *screen; -@property (nonatomic, assign) UIWindowLevel windowLevel; -@property (nonatomic,retain) UIViewController *rootViewController; +@property (nonatomic, strong) UIScreen *screen; +@property (nonatomic, assign) UIWindowLevel windowLevel; +@property (nonatomic, strong) UIViewController *rootViewController; @end diff --git a/UIKit/Classes/UIWindow.m b/UIKit/Classes/UIWindow.m index af5f20d4..fa9767b0 100644 --- a/UIKit/Classes/UIWindow.m +++ b/UIKit/Classes/UIWindow.m @@ -31,14 +31,14 @@ #import "UIView+UIPrivate.h" #import "UIScreen+UIPrivate.h" #import "UIScreenAppKitIntegration.h" -#import "UIApplication+UIPrivate.h" -#import "UIEvent.h" +#import "UIApplication.h" #import "UITouch+UIPrivate.h" #import "UIScreenMode.h" #import "UIResponderAppKitIntegration.h" #import "UIViewController.h" -#import "UIGestureRecognizerSubclass.h" #import "UIGestureRecognizer+UIPrivate.h" +#import "UITouchEvent.h" +#import "UIKitView.h" #import #import @@ -55,6 +55,7 @@ NSString *const UIKeyboardDidShowNotification = @"UIKeyboardDidShowNotification"; NSString *const UIKeyboardWillHideNotification = @"UIKeyboardWillHideNotification"; NSString *const UIKeyboardDidHideNotification = @"UIKeyboardDidHideNotification"; +NSString *const UIKeyboardWillChangeFrameNotification = @"UIKeyboardWillChangeFrameNotification"; NSString *const UIKeyboardFrameBeginUserInfoKey = @"UIKeyboardFrameBeginUserInfoKey"; NSString *const UIKeyboardFrameEndUserInfoKey = @"UIKeyboardFrameEndUserInfoKey"; @@ -66,9 +67,10 @@ NSString *const UIKeyboardCenterEndUserInfoKey = @"UIKeyboardCenterEndUserInfoKey"; NSString *const UIKeyboardBoundsUserInfoKey = @"UIKeyboardBoundsUserInfoKey"; - -@implementation UIWindow -@synthesize screen=_screen, rootViewController=_rootViewController; +@implementation UIWindow { + __weak UIResponder *_firstResponder; + NSUndoManager *_undoManager; +} - (id)initWithFrame:(CGRect)theFrame { @@ -77,6 +79,9 @@ - (id)initWithFrame:(CGRect)theFrame [self _makeHidden]; // do this first because before the screen is set, it will prevent any visibility notifications from being sent. self.screen = [UIScreen mainScreen]; self.opaque = NO; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_NSWindowDidBecomeKeyNotification:) name:NSWindowDidBecomeKeyNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_NSWindowDidResignKeyNotification:) name:NSWindowDidResignKeyNotification object:nil]; } return self; } @@ -85,9 +90,6 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [self _makeHidden]; // I don't really like this here, but the real UIKit seems to do something like this on window destruction as it sends a notification and we also need to remove it from the app's list of windows - [_screen release]; - [_undoManager release]; - [_rootViewController release]; // since UIView's dealloc is called after this one, it's hard ot say what might happen in there due to all of the subview removal stuff // so it's safer to make sure these things are nil now rather than potential garbage. I don't like how much work UIView's -dealloc is doing @@ -96,7 +98,6 @@ - (void)dealloc _undoManager = nil; _rootViewController = nil; - [super dealloc]; } - (UIResponder *)_firstResponder @@ -138,13 +139,23 @@ - (void)setRootViewController:(UIViewController *)rootViewController { if (rootViewController != _rootViewController) { [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; - [_rootViewController release]; - _rootViewController = [rootViewController retain]; - _rootViewController.view.frame = self.bounds; // unsure about this + + const BOOL was = [UIView areAnimationsEnabled]; + [UIView setAnimationsEnabled:NO]; + _rootViewController = rootViewController; + _rootViewController.view.frame = self.bounds; [self addSubview:_rootViewController.view]; + [self layoutIfNeeded]; + [UIView setAnimationsEnabled:was]; } } +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + _rootViewController.view.frame = self.bounds; +} + - (void)setScreen:(UIScreen *)theScreen { if (theScreen != _screen) { @@ -154,8 +165,7 @@ - (void)setScreen:(UIScreen *)theScreen [self _makeHidden]; [self.layer removeFromSuperlayer]; - [_screen release]; - _screen = [theScreen retain]; + _screen = theScreen; [[_screen _layer] addSublayer:self.layer]; if (!wasHidden) { @@ -232,26 +242,50 @@ - (CGRect)convertRect:(CGRect)toConvert toWindow:(UIWindow *)toWindow return CGRectMake(convertedOrigin.x, convertedOrigin.y, toConvert.size.width, toConvert.size.height); } -- (void)becomeKeyWindow +- (void)makeKeyWindow { - if ([[self _firstResponder] respondsToSelector:@selector(becomeKeyWindow)]) { - [(id)[self _firstResponder] becomeKeyWindow]; + if (!self.isKeyWindow && self.screen) { + // this check is here because if the underlying screen's UIKitView is AppKit's keyWindow, then + // we must resign it because UIKit thinks it's currently the key window, too, so we do that here. + if ([self.screen.keyWindow isKeyWindow]) { + [self.screen.keyWindow resignKeyWindow]; + } + + // now we set the screen's key window to ourself - note that this doesn't really make it the key + // window yet from an external point of view... + [self.screen _setKeyWindow:self]; + + // if it turns out we're now the key window, it means this window is ultimately within a UIKitView + // that's the current AppKit key window, too, so we make it so. if we are NOT the key window, we + // need to try to tell AppKit to make the UIKitView we're on the key window. If that works out, + // we will get a notification and -becomeKeyWindow will be called from there, so we don't have to + // do anything else in here. + if (self.isKeyWindow) { + [self becomeKeyWindow]; + } else { + [[self.screen.UIKitView window] makeFirstResponder:self.screen.UIKitView]; + [[self.screen.UIKitView window] makeKeyWindow]; + } } - [[NSNotificationCenter defaultCenter] postNotificationName:UIWindowDidBecomeKeyNotification object:self]; } -- (void)makeKeyWindow +- (BOOL)isKeyWindow { - if (!self.isKeyWindow) { - [[UIApplication sharedApplication].keyWindow resignKeyWindow]; - [[UIApplication sharedApplication] _setKeyWindow:self]; - [self becomeKeyWindow]; + // only return YES if we have a screen and our screen's UIKitView is on the AppKit key window + + if (self.screen.keyWindow == self) { + return [[self.screen.UIKitView window] isKeyWindow]; } + + return NO; } -- (BOOL)isKeyWindow +- (void)becomeKeyWindow { - return ([UIApplication sharedApplication].keyWindow == self); + if ([[self _firstResponder] respondsToSelector:@selector(becomeKeyWindow)]) { + [(id)[self _firstResponder] becomeKeyWindow]; + } + [[NSNotificationCenter defaultCenter] postNotificationName:UIWindowDidBecomeKeyNotification object:self]; } - (void)resignKeyWindow @@ -259,15 +293,47 @@ - (void)resignKeyWindow if ([[self _firstResponder] respondsToSelector:@selector(resignKeyWindow)]) { [(id)[self _firstResponder] resignKeyWindow]; } + [[NSNotificationCenter defaultCenter] postNotificationName:UIWindowDidResignKeyNotification object:self]; } +- (void)_NSWindowDidBecomeKeyNotification:(NSNotification *)note +{ + NSWindow *nativeWindow = [note object]; + + // when the underlying screen's NSWindow becomes key, we can use the keyWindow property the screen itself + // to know if this UIWindow should become key again now or not. If things match up, we fire off -becomeKeyWindow + // again to let the app know this happened. Normally iOS doesn't run into situations where the user can change + // the key window out from under the app, so this is going to be somewhat unusual UIKit behavior... + if ([[self.screen.UIKitView window] isEqual:nativeWindow]) { + if (self.screen.keyWindow == self) { + [self becomeKeyWindow]; + } + } +} + +- (void)_NSWindowDidResignKeyNotification:(NSNotification *)note +{ + NSWindow *nativeWindow = [note object]; + + // if the resigned key window is the same window that hosts our underlying screen, then we need to resign + // this UIWindow, too. note that it does NOT actually unset the keyWindow property for the UIScreen! + // this is because if the user clicks back in the screen's window, we need a way to reconnect this UIWindow + // as the key window, too, so that's how that is done. + if ([[self.screen.UIKitView window] isEqual:nativeWindow]) { + if (self.screen.keyWindow == self) { + [self resignKeyWindow]; + } + } +} + - (void)_makeHidden { if (!self.hidden) { [super setHidden:YES]; + if (self.screen) { - [[UIApplication sharedApplication] _windowDidBecomeHidden:self]; + [self.screen _removeWindow:self]; [[NSNotificationCenter defaultCenter] postNotificationName:UIWindowDidBecomeHiddenNotification object:self]; } } @@ -277,8 +343,9 @@ - (void)_makeVisible { if (self.hidden) { [super setHidden:NO]; + if (self.screen) { - [[UIApplication sharedApplication] _windowDidBecomeVisible:self]; + [self.screen _addWindow:self]; [[NSNotificationCenter defaultCenter] postNotificationName:UIWindowDidBecomeVisibleNotification object:self]; } } @@ -311,71 +378,159 @@ - (UIWindowLevel)windowLevel - (void)sendEvent:(UIEvent *)event { - if (event.type == UIEventTypeTouches) { - NSSet *touches = [event touchesForWindow:self]; - NSMutableSet *gestureRecognizers = [NSMutableSet setWithCapacity:0]; + if ([event isKindOfClass:[UITouchEvent class]]) { + [self _processTouchEvent:(UITouchEvent *)event]; + } +} - for (UITouch *touch in touches) { - [gestureRecognizers addObjectsFromArray:touch.gestureRecognizers]; +- (void)_processTouchEvent:(UITouchEvent *)event +{ + // we only support a single touch, so there is a *lot* in here that would break or need serious changes + // to properly support mulitouch. I still don't really like how all this works - especially with the + // gesture recognizers, but I've been struggling to come up with a better way for far too long and just + // have to deal with what I've got now. + + // if there's no touch for this window, return immediately + if (event.touch.window != self) { + return; + } + + // normally there'd be no need to retain the view here, but this works around a strange problem I ran into. + // what can happen is, now that UIView's -removeFromSuperview will remove the view from the active touch + // instead of just cancel the touch (which is how I had implemented it previously - which was wrong), the + // situation can arise where, in response to a touch event of some kind, the view may remove itself from its + // superview in some fashion, which means that the handling of the touchesEnded:withEvent: (or whatever) + // methods could somehow result in the view itself being destroyed before the method is even finished running! + // a strong reference here works around this problem since the view is kept alive until we're done with it. + // If someone can figure out some other, better way to fix this without it having to have this hacky-feeling + // stuff here, that'd be cool, but be aware that this is here for a reason and that the problem it prevents is + // somewhat contrived but not uncommon. + UIView *view = event.touch.view; + + // first deliver new touches to all possible gesture recognizers + if (event.touch.phase == UITouchPhaseBegan) { + for (UIView *subview = view; subview != nil; subview = [subview superview]) { + for (UIGestureRecognizer *gesture in subview.gestureRecognizers) { + [gesture _beginTrackingTouch:event.touch withEvent:event]; + } } + } - for (UIGestureRecognizer *recognizer in gestureRecognizers) { - [recognizer _recognizeTouches:touches withEvent:event]; - } + BOOL gestureRecognized = NO; + BOOL possibleGestures = NO; + BOOL delaysTouchesBegan = NO; + BOOL delaysTouchesEnded = NO; + BOOL cancelsTouches = NO; - for (UITouch *touch in touches) { - // normally there'd be no need to retain the view here, but this works around a strange problem I ran into. - // what can happen is, now that UIView's -removeFromSuperview will remove the view from the active touch - // instead of just cancel the touch (which is how I had implemented it previously - which was wrong), the - // situation can arise where, in response to a touch event of some kind, the view may remove itself from its - // superview in some fashion, which means that the handling of the touchesEnded:withEvent: (or whatever) - // methods could somehow result in the view itself being destroyed before the method is even finished running! - // I ran into this in particular with a load more button in Twitterrific which would crash in UIControl's - // touchesEnded: implemention after sending actions to the registered targets (because one of those targets - // ended up removing the button from view and thus reducing its retain count to 0). For some reason, even - // though I attempted to rearrange stuff in UIControl so that actions were always the last thing done, it'd - // still end up crashing when one of the internal methods returned to touchesEnded:, which didn't make sense - // to me because there was no code after that (at the time) and therefore it should just have been unwinding - // the stack to eventually get back here and all should have been okay. I never figured out exactly why that - // crashed in that way, but by putting a retain here it works around this problem and perhaps others that have - // gone so-far unnoticed. Converting to ARC should also work with this solution because there will be a local - // strong reference to the view retainined throughout the rest of this logic and thus the same protection - // against mid-method view destrustion should be provided under ARC. If someone can figure out some other, - // better way to fix this without it having to have this hacky-feeling retain here, that'd be cool, but be - // aware that this is here for a reason and that the problem it prevents is very rare and somewhat contrived. - UIView *view = [touch.view retain]; - - const UITouchPhase phase = touch.phase; - const _UITouchGesture gesture = [touch _gesture]; + // then allow all tracking gesture recognizers to have their way with the touches in this event before + // anything else is done. + for (UIGestureRecognizer *gesture in event.touch.gestureRecognizers) { + [gesture _continueTrackingWithEvent:event]; + + const BOOL recognized = (gesture.state == UIGestureRecognizerStateRecognized || gesture.state == UIGestureRecognizerStateBegan); + const BOOL possible = (gesture.state == UIGestureRecognizerStatePossible); + + gestureRecognized |= recognized; + possibleGestures |= possible; + + if (recognized || possible) { + delaysTouchesBegan |= gesture.delaysTouchesBegan; - if (phase == UITouchPhaseBegan) { - [view touchesBegan:touches withEvent:event]; - } else if (phase == UITouchPhaseMoved) { - [view touchesMoved:touches withEvent:event]; - } else if (phase == UITouchPhaseEnded) { - [view touchesEnded:touches withEvent:event]; - } else if (phase == UITouchPhaseCancelled) { - [view touchesCancelled:touches withEvent:event]; - } else if (phase == _UITouchPhaseDiscreteGesture && gesture == _UITouchDiscreteGestureMouseMove) { - if ([view hitTest:[touch locationInView:view] withEvent:event]) { - [view mouseMoved:[touch _delta] withEvent:event]; + // special case for scroll views so that -delaysContentTouches works somewhat as expected + // likely this is pretty wrong, but it should work well enough for most normal cases, I suspect. + if ([gesture.view isKindOfClass:[UIScrollView class]]) { + UIScrollView *scrollView = (UIScrollView *)gesture.view; + + if ([gesture isEqual:scrollView.panGestureRecognizer] || [gesture isEqual:scrollView.scrollWheelGestureRecognizer]) { + delaysTouchesBegan |= scrollView.delaysContentTouches; } - } else if (phase == _UITouchPhaseDiscreteGesture && gesture == _UITouchDiscreteGestureRightClick) { - [view rightClick:touch withEvent:event]; - } else if ((phase == _UITouchPhaseDiscreteGesture && gesture == _UITouchDiscreteGestureScrollWheel) || - (phase == _UITouchPhaseGestureChanged && gesture == _UITouchGesturePan)) { - [view scrollWheelMoved:[touch _delta] withEvent:event]; } - - NSCursor *newCursor = [view mouseCursorForEvent:event] ?: [NSCursor arrowCursor]; - - if ([NSCursor currentCursor] != newCursor) { - [newCursor set]; + } + + if (recognized) { + delaysTouchesEnded |= gesture.delaysTouchesEnded; + cancelsTouches |= gesture.cancelsTouchesInView; + } + } + + if (event.isDiscreteGesture) { + // this should prevent delivery of the "touches" down the responder chain in roughly the same way a normal non- + // discrete gesture would based on the settings of the in-play gesture recognizers. + if (!gestureRecognized || (gestureRecognized && !cancelsTouches && !delaysTouchesBegan)) { + if (event.touchEventGesture == UITouchEventGestureRightClick) { + [view rightClick:event.touch withEvent:event]; + } else if (event.touchEventGesture == UITouchEventGestureScrollWheel) { + [view scrollWheelMoved:event.translation withEvent:event]; + } else if (event.touchEventGesture == UITouchEventGestureMouseMove) { + [view mouseMoved:event.touch withEvent:event]; + } else if (event.touchEventGesture == UITouchEventGestureMouseEntered) { + [view mouseEntered:event.touch.view withEvent:event]; + } else if (event.touchEventGesture == UITouchEventGestureMouseExited) { + [view mouseExited:event.touch.view withEvent:event]; + } + } + } else { + if (event.touch.phase == UITouchPhaseBegan) { + if ((!gestureRecognized && !possibleGestures) || !delaysTouchesBegan) { + [view touchesBegan:event.allTouches withEvent:event]; + event.touch.wasDeliveredToView = YES; } + } else if (delaysTouchesBegan && gestureRecognized && !event.touch.wasDeliveredToView) { + // if we were delaying touches began and a gesture gets recognized, and we never sent it to the view, + // we need to throw it away and be sure we never send it to the view for the duration of the gesture + // so we do this by marking it both delivered and cancelled without actually sending it to the view. + event.touch.wasDeliveredToView = YES; + event.touch.wasCancelledInView = YES; + } else if (delaysTouchesBegan && !gestureRecognized && !possibleGestures && !event.touch.wasDeliveredToView && event.touch.phase != UITouchPhaseCancelled) { + // need to fake-send a touches began using the cached time and location in the touch + // a followup move or ended or cancelled touch will be sent below if necessary + const NSTimeInterval currentTimestamp = event.touch.timestamp; + const UITouchPhase currentPhase = event.touch.phase; + const CGPoint currentLocation = event.touch.locationOnScreen; - [view release]; + event.touch.timestamp = event.touch.beganPhaseTimestamp; + event.touch.locationOnScreen = event.touch.beganPhaseLocationOnScreen; + event.touch.phase = UITouchPhaseBegan; + + [view touchesBegan:event.allTouches withEvent:event]; + event.touch.wasDeliveredToView = YES; + + event.touch.phase = currentPhase; + event.touch.locationOnScreen = currentLocation; + event.touch.timestamp = currentTimestamp; + } + + if (event.touch.phase != UITouchPhaseBegan && event.touch.wasDeliveredToView && !event.touch.wasCancelledInView) { + if (event.touch.phase == UITouchPhaseCancelled) { + [view touchesCancelled:event.allTouches withEvent:event]; + event.touch.wasCancelledInView = YES; + } else if (gestureRecognized && (cancelsTouches || (event.touch.phase == UITouchPhaseEnded && delaysTouchesEnded))) { + // since we're supposed to cancel touches, mark it cancelled, send it to the view, and + // then change it back to whatever it was because there might be other gesture recognizers + // that are still using the touch for whatever reason and aren't going to expect it suddenly + // cancelled. (technically cancelled touches are, I think, meant to be a last resort.. + // the sort of thing that happens when a phone call comes in or a modal window comes up) + const UITouchPhase currentPhase = event.touch.phase; + + event.touch.phase = UITouchPhaseCancelled; + + [view touchesCancelled:event.allTouches withEvent:event]; + event.touch.wasCancelledInView = YES; + + event.touch.phase = currentPhase; + } else if (event.touch.phase == UITouchPhaseMoved) { + [view touchesMoved:event.allTouches withEvent:event]; + } else if (event.touch.phase == UITouchPhaseEnded) { + [view touchesEnded:event.allTouches withEvent:event]; + } } } + + NSCursor *newCursor = [view mouseCursorForEvent:event] ?: [NSCursor arrowCursor]; + + if ([NSCursor currentCursor] != newCursor) { + [newCursor set]; + } } @end diff --git a/UIKit/UIKit.xcodeproj/project.pbxproj b/UIKit/UIKit.xcodeproj/project.pbxproj index d47a64a1..187ba57a 100644 --- a/UIKit/UIKit.xcodeproj/project.pbxproj +++ b/UIKit/UIKit.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 14100F70175FB9C700269BBF /* UINSResponderShim.h in Headers */ = {isa = PBXBuildFile; fileRef = 14100F6E175FB9C700269BBF /* UINSResponderShim.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 14100F71175FB9C700269BBF /* UINSResponderShim.m in Sources */ = {isa = PBXBuildFile; fileRef = 14100F6F175FB9C700269BBF /* UINSResponderShim.m */; }; 1413D21213D72A06004D77E9 /* UIScrollViewAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1413D20C13D72A06004D77E9 /* UIScrollViewAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1413D21313D72A06004D77E9 /* UIScrollViewAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 1413D20D13D72A06004D77E9 /* UIScrollViewAnimation.m */; }; 1413D21413D72A06004D77E9 /* UIScrollViewAnimationDeceleration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1413D20E13D72A06004D77E9 /* UIScrollViewAnimationDeceleration.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -20,6 +22,7 @@ 1426A02715701598004C2C9A /* arrow-top@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1426A02215701598004C2C9A /* arrow-top@2x.png */; }; 1426FFDD129ADEA300BD31E5 /* UIControlAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1426FFDB129ADEA300BD31E5 /* UIControlAction.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1426FFDE129ADEA300BD31E5 /* UIControlAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 1426FFDC129ADEA300BD31E5 /* UIControlAction.m */; }; + 1434E8661770F4570023F2C5 /* UIViewControllerAppKitIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 1434E8651770F4570023F2C5 /* UIViewControllerAppKitIntegration.h */; settings = {ATTRIBUTES = (Private, ); }; }; 144156DB1284A22200532FE2 /* UIToolbarButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 144156D91284A22200532FE2 /* UIToolbarButton.h */; settings = {ATTRIBUTES = (Private, ); }; }; 144156DC1284A22200532FE2 /* UIToolbarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 144156DA1284A22200532FE2 /* UIToolbarButton.m */; }; 1443B06C13E06081001D7EC1 /* UIBackgroundTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 1443B06A13E06081001D7EC1 /* UIBackgroundTask.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -36,16 +39,15 @@ 145335861226F3490005644F /* UICustomNSClipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 145335841226F3490005644F /* UICustomNSClipView.m */; }; 14541DB21360D6F300C1006D /* UIPhotosAlbum.h in Headers */ = {isa = PBXBuildFile; fileRef = 14541DB01360D6F300C1006D /* UIPhotosAlbum.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14541DB31360D6F300C1006D /* UIPhotosAlbum.m in Sources */ = {isa = PBXBuildFile; fileRef = 14541DB11360D6F300C1006D /* UIPhotosAlbum.m */; }; - 145576231541DC560029EF4D /* UIAppearanceInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = 145576221541DC560029EF4D /* UIAppearanceInstance.h */; }; + 145576231541DC560029EF4D /* UIAppearanceInstance.h in Headers */ = {isa = PBXBuildFile; fileRef = 145576221541DC560029EF4D /* UIAppearanceInstance.h */; settings = {ATTRIBUTES = (Private, ); }; }; 145576261541DC830029EF4D /* UIAppearanceInstance.m in Sources */ = {isa = PBXBuildFile; fileRef = 145576251541DC830029EF4D /* UIAppearanceInstance.m */; }; - 1457DD3F128DDE610057A7F9 /* UITransitionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1457DD3D128DDE610057A7F9 /* UITransitionView.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 1457DD40128DDE610057A7F9 /* UITransitionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1457DD3E128DDE610057A7F9 /* UITransitionView.m */; }; - 145BE31D15754F2400C41D70 /* UIColorRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 145BE31B15754F2400C41D70 /* UIColorRep.h */; }; + 145BE31D15754F2400C41D70 /* UIColorRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 145BE31B15754F2400C41D70 /* UIColorRep.h */; settings = {ATTRIBUTES = (Private, ); }; }; 145BE31E15754F2400C41D70 /* UIColorRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 145BE31C15754F2400C41D70 /* UIColorRep.m */; }; - 145BE3211575523000C41D70 /* UIColor+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 145BE3201575523000C41D70 /* UIColor+UIPrivate.h */; }; + 145BE3211575523000C41D70 /* UIColor+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 145BE3201575523000C41D70 /* UIColor+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 145D0B0517949A6800FB569B /* UINavigationItem+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 145D0B0417949A6800FB569B /* UINavigationItem+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1464960B11FF7AE500ECEC7A /* back-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = 1464960711FF7AE500ECEC7A /* back-highlighted.png */; }; 1464960C11FF7AE500ECEC7A /* back.png in Resources */ = {isa = PBXBuildFile; fileRef = 1464960811FF7AE500ECEC7A /* back.png */; }; - 14711394156FC83F00251B2E /* UIImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 14711392156FC83F00251B2E /* UIImageRep.h */; }; + 14711394156FC83F00251B2E /* UIImageRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 14711392156FC83F00251B2E /* UIImageRep.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14711395156FC83F00251B2E /* UIImageRep.m in Sources */ = {isa = PBXBuildFile; fileRef = 14711393156FC83F00251B2E /* UIImageRep.m */; }; 14805D4112A6B0E80080C4BA /* UINSClipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 14805D3F12A6B0E80080C4BA /* UINSClipView.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14805D4212A6B0E80080C4BA /* UINSClipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 14805D4012A6B0E80080C4BA /* UINSClipView.m */; }; @@ -109,7 +111,7 @@ 1489859F12EE2CFF003D4751 /* UIImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1489851912EE2CFE003D4751 /* UIImagePickerController.m */; }; 148985A012EE2CFF003D4751 /* UIImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1489851A12EE2CFE003D4751 /* UIImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 148985A112EE2CFF003D4751 /* UIImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1489851B12EE2CFE003D4751 /* UIImageView.m */; }; - 148985A212EE2CFF003D4751 /* UIKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 1489851C12EE2CFE003D4751 /* UIKey.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 148985A212EE2CFF003D4751 /* UIKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 1489851C12EE2CFE003D4751 /* UIKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; 148985A312EE2CFF003D4751 /* UIKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 1489851D12EE2CFE003D4751 /* UIKey.m */; }; 148985A412EE2CFF003D4751 /* UIKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 1489851E12EE2CFE003D4751 /* UIKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 148985A512EE2CFF003D4751 /* UIKitView.h in Headers */ = {isa = PBXBuildFile; fileRef = 1489851F12EE2CFE003D4751 /* UIKitView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -208,7 +210,6 @@ 148DEEA1156E945800E7B8DE /* button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 148DEE94156E945800E7B8DE /* button@2x.png */; }; 1490AFE01219C31C00774286 /* UIPopoverController+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1490AFDE1219C31C00774286 /* UIPopoverController+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 149148BC12EE45ED00F7C34E /* UIGestureRecognizerSubclass.h in Headers */ = {isa = PBXBuildFile; fileRef = 149148BA12EE45ED00F7C34E /* UIGestureRecognizerSubclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 14A726D21213303400648C9B /* UIApplication+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726AF1213303400648C9B /* UIApplication+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14A726D41213303400648C9B /* UIControl+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726B11213303400648C9B /* UIControl+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14A726D71213303400648C9B /* UIImage+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726B41213303400648C9B /* UIImage+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14A726D81213303400648C9B /* UIImageView+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726B51213303400648C9B /* UIImageView+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -216,10 +217,9 @@ 14A726DC1213303400648C9B /* UITableViewCell+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726B91213303400648C9B /* UITableViewCell+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14A726DD1213303400648C9B /* UITouch+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726BA1213303400648C9B /* UITouch+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14A726DE1213303400648C9B /* UIView+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726BB1213303400648C9B /* UIView+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 14A726DF1213303400648C9B /* UIViewController+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726BC1213303400648C9B /* UIViewController+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14A726E01213303400648C9B /* UIWindow+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A726BD1213303400648C9B /* UIWindow+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 14BF16DB12E621EB007DAA01 /* UIViewBlockAnimationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BF16D912E621EB007DAA01 /* UIViewBlockAnimationDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 14BF16DC12E621EB007DAA01 /* UIViewBlockAnimationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14BF16DA12E621EB007DAA01 /* UIViewBlockAnimationDelegate.m */; }; + 14BA42F217554D0200891B6D /* UITouchEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BA42F017554D0200891B6D /* UITouchEvent.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 14BA42F317554D0200891B6D /* UITouchEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 14BA42F117554D0200891B6D /* UITouchEvent.m */; }; 14C0715E13CF5A2400B76E35 /* UIAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C0715C13CF5A2300B76E35 /* UIAction.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14C0715F13CF5A2400B76E35 /* UIAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C0715D13CF5A2300B76E35 /* UIAction.m */; }; 14C0716213CF66B800B76E35 /* UIScrollWheelGestureRecognizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 14C0716013CF66B600B76E35 /* UIScrollWheelGestureRecognizer.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -235,6 +235,8 @@ 14CC843711EFA8BA005988CC /* grabber.png in Resources */ = {isa = PBXBuildFile; fileRef = 14CC842F11EFA8BA005988CC /* grabber.png */; }; 14CC844111EFA901005988CC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14CC844011EFA901005988CC /* QuartzCore.framework */; }; 14CC844511EFA91A005988CC /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 14CC844411EFA91A005988CC /* SystemConfiguration.framework */; }; + 14D0601717303DC100C9A7C6 /* UINSApplicationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D0601517303DC100C9A7C6 /* UINSApplicationDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 14D0601817303DC100C9A7C6 /* UINSApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14D0601617303DC100C9A7C6 /* UINSApplicationDelegate.m */; }; 14D796381540A5DA00C02139 /* UIAppearanceProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D796361540A5DA00C02139 /* UIAppearanceProperty.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14D796391540A5DA00C02139 /* UIAppearanceProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 14D796371540A5DA00C02139 /* UIAppearanceProperty.m */; }; 14D8D941135DE90A00FE639A /* UIInputController.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D8D93F135DE90A00FE639A /* UIInputController.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -243,8 +245,6 @@ 14DD1C361289B4D500DCF231 /* button-highlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = 14DD1C341289B4D500DCF231 /* button-highlighted.png */; }; 14DD1C371289B4D500DCF231 /* button.png in Resources */ = {isa = PBXBuildFile; fileRef = 14DD1C351289B4D500DCF231 /* button.png */; }; 14E20663156FE88D0040349D /* UIImageAppKitIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 14E20662156FE88D0040349D /* UIImageAppKitIntegration.m */; }; - 14EEF76712DF67CF00EB7D95 /* UIEvent+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14EEF76512DF67CF00EB7D95 /* UIEvent+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 14EEF7A912DF6D9C00EB7D95 /* UIKey+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 14EEF7A812DF6D9C00EB7D95 /* UIKey+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14F0BC0D1288A67F00BA54F9 /* add.png in Resources */ = {isa = PBXBuildFile; fileRef = 14F0BC0B1288A67F00BA54F9 /* add.png */; }; 14F0BC0E1288A67F00BA54F9 /* reply.png in Resources */ = {isa = PBXBuildFile; fileRef = 14F0BC0C1288A67F00BA54F9 /* reply.png */; }; 14F56F3D12664D350045EC82 /* arrow-bottom.png in Resources */ = {isa = PBXBuildFile; fileRef = 14F56F3812664D350045EC82 /* arrow-bottom.png */; }; @@ -273,17 +273,15 @@ 14FDE99C153C9A1800A2D499 /* UIAppearance.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FDE99A153C9A1800A2D499 /* UIAppearance.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14FDE9A5153CAECA00A2D499 /* UIAppearanceProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FDE9A3153CAECA00A2D499 /* UIAppearanceProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14FDE9A6153CAECA00A2D499 /* UIAppearanceProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 14FDE9A4153CAECA00A2D499 /* UIAppearanceProxy.m */; }; + 14FE493A171C988B009C7794 /* UITextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 14FE4939171C988B009C7794 /* UITextInput.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 14FE4941171C9989009C7794 /* UITextInput.m in Sources */ = {isa = PBXBuildFile; fileRef = 14FE4940171C9989009C7794 /* UITextInput.m */; }; 38615C78133A81B900841EEA /* UIFont+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 38615C77133A81B900841EEA /* UIFont+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 38E523B11339680400E041B3 /* UINavigationItem+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 38E523AF1339680400E041B3 /* UINavigationItem+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 38E523B513396B5B00E041B3 /* UINavigationBar+UIPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 38E523B413396B5B00E041B3 /* UINavigationBar+UIPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 537472D5133ADD4B00EBD5EA /* UIInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 537472D3133ADD4B00EBD5EA /* UIInterface.h */; settings = {ATTRIBUTES = (Public, ); }; }; 537472D6133ADD4B00EBD5EA /* UIInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 537472D4133ADD4B00EBD5EA /* UIInterface.m */; }; 7011107C133BE0F400C86512 /* UIDatePicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7011107A133BE0F300C86512 /* UIDatePicker.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7011107D133BE0F400C86512 /* UIDatePicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 7011107B133BE0F300C86512 /* UIDatePicker.m */; }; 7806ED2A133A1D7500273BC6 /* UITabBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 7806ED28133A1D7500273BC6 /* UITabBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7806ED2B133A1D7500273BC6 /* UITabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 7806ED29133A1D7500273BC6 /* UITabBar.m */; }; - 789CF898133A3CD500250AB4 /* NSFetchedResultsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 789CF896133A3CD500250AB4 /* NSFetchedResultsController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 789CF899133A3CD500250AB4 /* NSFetchedResultsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 789CF897133A3CD500250AB4 /* NSFetchedResultsController.m */; }; 78CB48AC133A9C51008636DA /* UISearchBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 78CB48AA133A9C51008636DA /* UISearchBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 78CB48AD133A9C51008636DA /* UISearchBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 78CB48AB133A9C51008636DA /* UISearchBar.m */; }; 78CB48B0133AA536008636DA /* UITabBarItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 78CB48AE133AA535008636DA /* UITabBarItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -303,6 +301,8 @@ 0867D69BFE84028FC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 0867D6A5FE840307C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 14100F6E175FB9C700269BBF /* UINSResponderShim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UINSResponderShim.h; sourceTree = ""; }; + 14100F6F175FB9C700269BBF /* UINSResponderShim.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UINSResponderShim.m; sourceTree = ""; }; 1413D20C13D72A06004D77E9 /* UIScrollViewAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIScrollViewAnimation.h; sourceTree = ""; }; 1413D20D13D72A06004D77E9 /* UIScrollViewAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIScrollViewAnimation.m; sourceTree = ""; }; 1413D20E13D72A06004D77E9 /* UIScrollViewAnimationDeceleration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIScrollViewAnimationDeceleration.h; sourceTree = ""; }; @@ -316,6 +316,7 @@ 1426A02215701598004C2C9A /* arrow-top@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " arrow-top@2x.png"; path = "Resources/ arrow-top@2x.png"; sourceTree = ""; }; 1426FFDB129ADEA300BD31E5 /* UIControlAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIControlAction.h; sourceTree = ""; }; 1426FFDC129ADEA300BD31E5 /* UIControlAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIControlAction.m; sourceTree = ""; }; + 1434E8651770F4570023F2C5 /* UIViewControllerAppKitIntegration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIViewControllerAppKitIntegration.h; sourceTree = ""; }; 144156D91284A22200532FE2 /* UIToolbarButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIToolbarButton.h; sourceTree = ""; }; 144156DA1284A22200532FE2 /* UIToolbarButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIToolbarButton.m; sourceTree = ""; }; 1443B06A13E06081001D7EC1 /* UIBackgroundTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIBackgroundTask.h; sourceTree = ""; }; @@ -334,11 +335,10 @@ 14541DB11360D6F300C1006D /* UIPhotosAlbum.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIPhotosAlbum.m; sourceTree = ""; }; 145576221541DC560029EF4D /* UIAppearanceInstance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppearanceInstance.h; sourceTree = ""; }; 145576251541DC830029EF4D /* UIAppearanceInstance.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppearanceInstance.m; sourceTree = ""; }; - 1457DD3D128DDE610057A7F9 /* UITransitionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITransitionView.h; sourceTree = ""; }; - 1457DD3E128DDE610057A7F9 /* UITransitionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITransitionView.m; sourceTree = ""; }; 145BE31B15754F2400C41D70 /* UIColorRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIColorRep.h; sourceTree = ""; }; 145BE31C15754F2400C41D70 /* UIColorRep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIColorRep.m; sourceTree = ""; }; 145BE3201575523000C41D70 /* UIColor+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+UIPrivate.h"; sourceTree = ""; }; + 145D0B0417949A6800FB569B /* UINavigationItem+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationItem+UIPrivate.h"; sourceTree = ""; }; 1464960711FF7AE500ECEC7A /* back-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " back-highlighted.png"; path = "Resources/ back-highlighted.png"; sourceTree = ""; }; 1464960811FF7AE500ECEC7A /* back.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " back.png"; path = "Resources/ back.png"; sourceTree = ""; }; 14711392156FC83F00251B2E /* UIImageRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIImageRep.h; sourceTree = ""; }; @@ -504,7 +504,6 @@ 148DEE94156E945800E7B8DE /* button@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " button@2x.png"; path = "Resources/ button@2x.png"; sourceTree = ""; }; 1490AFDE1219C31C00774286 /* UIPopoverController+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIPopoverController+UIPrivate.h"; sourceTree = ""; }; 149148BA12EE45ED00F7C34E /* UIGestureRecognizerSubclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIGestureRecognizerSubclass.h; sourceTree = ""; }; - 14A726AF1213303400648C9B /* UIApplication+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIApplication+UIPrivate.h"; sourceTree = ""; }; 14A726B11213303400648C9B /* UIControl+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+UIPrivate.h"; sourceTree = ""; }; 14A726B41213303400648C9B /* UIImage+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+UIPrivate.h"; sourceTree = ""; }; 14A726B51213303400648C9B /* UIImageView+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+UIPrivate.h"; sourceTree = ""; }; @@ -512,10 +511,9 @@ 14A726B91213303400648C9B /* UITableViewCell+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewCell+UIPrivate.h"; sourceTree = ""; }; 14A726BA1213303400648C9B /* UITouch+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITouch+UIPrivate.h"; sourceTree = ""; }; 14A726BB1213303400648C9B /* UIView+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+UIPrivate.h"; sourceTree = ""; }; - 14A726BC1213303400648C9B /* UIViewController+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+UIPrivate.h"; sourceTree = ""; }; 14A726BD1213303400648C9B /* UIWindow+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIWindow+UIPrivate.h"; sourceTree = ""; }; - 14BF16D912E621EB007DAA01 /* UIViewBlockAnimationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIViewBlockAnimationDelegate.h; sourceTree = ""; }; - 14BF16DA12E621EB007DAA01 /* UIViewBlockAnimationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIViewBlockAnimationDelegate.m; sourceTree = ""; }; + 14BA42F017554D0200891B6D /* UITouchEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITouchEvent.h; sourceTree = ""; }; + 14BA42F117554D0200891B6D /* UITouchEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITouchEvent.m; sourceTree = ""; }; 14C0715C13CF5A2300B76E35 /* UIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAction.h; sourceTree = ""; }; 14C0715D13CF5A2300B76E35 /* UIAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAction.m; sourceTree = ""; }; 14C0716013CF66B600B76E35 /* UIScrollWheelGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIScrollWheelGestureRecognizer.h; sourceTree = ""; }; @@ -531,6 +529,8 @@ 14CC842F11EFA8BA005988CC /* grabber.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " grabber.png"; path = "Resources/ grabber.png"; sourceTree = ""; }; 14CC844011EFA901005988CC /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 14CC844411EFA91A005988CC /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 14D0601517303DC100C9A7C6 /* UINSApplicationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UINSApplicationDelegate.h; sourceTree = ""; }; + 14D0601617303DC100C9A7C6 /* UINSApplicationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UINSApplicationDelegate.m; sourceTree = ""; }; 14D796361540A5DA00C02139 /* UIAppearanceProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppearanceProperty.h; sourceTree = ""; }; 14D796371540A5DA00C02139 /* UIAppearanceProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppearanceProperty.m; sourceTree = ""; }; 14D8D93F135DE90A00FE639A /* UIInputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIInputController.h; sourceTree = ""; }; @@ -539,8 +539,6 @@ 14DD1C341289B4D500DCF231 /* button-highlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " button-highlighted.png"; path = "Resources/ button-highlighted.png"; sourceTree = ""; }; 14DD1C351289B4D500DCF231 /* button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " button.png"; path = "Resources/ button.png"; sourceTree = ""; }; 14E20662156FE88D0040349D /* UIImageAppKitIntegration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIImageAppKitIntegration.m; sourceTree = ""; }; - 14EEF76512DF67CF00EB7D95 /* UIEvent+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIEvent+UIPrivate.h"; sourceTree = ""; }; - 14EEF7A812DF6D9C00EB7D95 /* UIKey+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIKey+UIPrivate.h"; sourceTree = ""; }; 14F0BC0B1288A67F00BA54F9 /* add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " add.png"; path = "Resources/ add.png"; sourceTree = ""; }; 14F0BC0C1288A67F00BA54F9 /* reply.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " reply.png"; path = "Resources/ reply.png"; sourceTree = ""; }; 14F56F3812664D350045EC82 /* arrow-bottom.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = " arrow-bottom.png"; path = "Resources/ arrow-bottom.png"; sourceTree = ""; }; @@ -569,18 +567,16 @@ 14FDE99A153C9A1800A2D499 /* UIAppearance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppearance.h; sourceTree = ""; }; 14FDE9A3153CAECA00A2D499 /* UIAppearanceProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAppearanceProxy.h; sourceTree = ""; }; 14FDE9A4153CAECA00A2D499 /* UIAppearanceProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAppearanceProxy.m; sourceTree = ""; }; + 14FE4939171C988B009C7794 /* UITextInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITextInput.h; sourceTree = ""; }; + 14FE4940171C9989009C7794 /* UITextInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITextInput.m; sourceTree = ""; }; 32DBCF5E0370ADEE00C91783 /* UIKit_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIKit_Prefix.pch; sourceTree = ""; }; 38615C77133A81B900841EEA /* UIFont+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+UIPrivate.h"; sourceTree = ""; }; - 38E523AF1339680400E041B3 /* UINavigationItem+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationItem+UIPrivate.h"; sourceTree = ""; }; - 38E523B413396B5B00E041B3 /* UINavigationBar+UIPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationBar+UIPrivate.h"; sourceTree = ""; }; 537472D3133ADD4B00EBD5EA /* UIInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIInterface.h; sourceTree = ""; }; 537472D4133ADD4B00EBD5EA /* UIInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIInterface.m; sourceTree = ""; }; 7011107A133BE0F300C86512 /* UIDatePicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIDatePicker.h; sourceTree = ""; }; 7011107B133BE0F300C86512 /* UIDatePicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIDatePicker.m; sourceTree = ""; }; 7806ED28133A1D7500273BC6 /* UITabBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITabBar.h; sourceTree = ""; }; 7806ED29133A1D7500273BC6 /* UITabBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UITabBar.m; sourceTree = ""; }; - 789CF896133A3CD500250AB4 /* NSFetchedResultsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSFetchedResultsController.h; sourceTree = ""; }; - 789CF897133A3CD500250AB4 /* NSFetchedResultsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSFetchedResultsController.m; sourceTree = ""; }; 78CB48AA133A9C51008636DA /* UISearchBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UISearchBar.h; sourceTree = ""; }; 78CB48AB133A9C51008636DA /* UISearchBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UISearchBar.m; sourceTree = ""; }; 78CB48AE133AA535008636DA /* UITabBarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UITabBarItem.h; sourceTree = ""; }; @@ -695,8 +691,6 @@ isa = PBXGroup; children = ( 148984E412EE2CFE003D4751 /* AppKitIntegration.h */, - 789CF896133A3CD500250AB4 /* NSFetchedResultsController.h */, - 789CF897133A3CD500250AB4 /* NSFetchedResultsController.m */, 148984E512EE2CFE003D4751 /* NSIndexPath+UITableView.h */, 148984E612EE2CFE003D4751 /* NSIndexPath+UITableView.m */, 148984E712EE2CFE003D4751 /* UIAcceleration.h */, @@ -759,8 +753,6 @@ 1489851B12EE2CFE003D4751 /* UIImageView.m */, 537472D3133ADD4B00EBD5EA /* UIInterface.h */, 537472D4133ADD4B00EBD5EA /* UIInterface.m */, - 1489851C12EE2CFE003D4751 /* UIKey.h */, - 1489851D12EE2CFE003D4751 /* UIKey.m */, 1489851E12EE2CFE003D4751 /* UIKit.h */, 1489851F12EE2CFE003D4751 /* UIKitView.h */, 1489852012EE2CFE003D4751 /* UIKitView.m */, @@ -842,6 +834,8 @@ 1489855612EE2CFE003D4751 /* UITapGestureRecognizer.m */, 1489855712EE2CFE003D4751 /* UITextField.h */, 1489855812EE2CFE003D4751 /* UITextField.m */, + 14FE4939171C988B009C7794 /* UITextInput.h */, + 14FE4940171C9989009C7794 /* UITextInput.m */, 1489855912EE2CFE003D4751 /* UITextInputTraits.h */, 1489855A12EE2CFE003D4751 /* UITextView.h */, 1489855B12EE2CFE003D4751 /* UITextView.m */, @@ -855,6 +849,7 @@ 1489856312EE2CFE003D4751 /* UIViewAdapter.m */, 1489856412EE2CFE003D4751 /* UIViewController.h */, 1489856512EE2CFE003D4751 /* UIViewController.m */, + 1434E8651770F4570023F2C5 /* UIViewControllerAppKitIntegration.h */, 1489856612EE2CFE003D4751 /* UIWebView.h */, 1489856712EE2CFE003D4751 /* UIWebView.m */, 1489856812EE2CFE003D4751 /* UIWindow.h */, @@ -890,10 +885,16 @@ 14711393156FC83F00251B2E /* UIImageRep.m */, 14D8D93F135DE90A00FE639A /* UIInputController.h */, 14D8D940135DE90A00FE639A /* UIInputController.m */, + 1489851C12EE2CFE003D4751 /* UIKey.h */, + 1489851D12EE2CFE003D4751 /* UIKey.m */, 14FA8C47121DA4A000C4264B /* UINinePartImage.h */, 14FA8C48121DA4A000C4264B /* UINinePartImage.m */, + 14D0601517303DC100C9A7C6 /* UINSApplicationDelegate.h */, + 14D0601617303DC100C9A7C6 /* UINSApplicationDelegate.m */, 14805D3F12A6B0E80080C4BA /* UINSClipView.h */, 14805D4012A6B0E80080C4BA /* UINSClipView.m */, + 14100F6E175FB9C700269BBF /* UINSResponderShim.h */, + 14100F6F175FB9C700269BBF /* UINSResponderShim.m */, 14541DB01360D6F300C1006D /* UIPhotosAlbum.h */, 14541DB11360D6F300C1006D /* UIPhotosAlbum.m */, 14CB384312689907003334AD /* UIPopoverNSWindow.h */, @@ -924,12 +925,10 @@ 14FA8C58121DA4A000C4264B /* UIThreePartImage.m */, 144156D91284A22200532FE2 /* UIToolbarButton.h */, 144156DA1284A22200532FE2 /* UIToolbarButton.m */, - 1457DD3D128DDE610057A7F9 /* UITransitionView.h */, - 1457DD3E128DDE610057A7F9 /* UITransitionView.m */, + 14BA42F017554D0200891B6D /* UITouchEvent.h */, + 14BA42F117554D0200891B6D /* UITouchEvent.m */, 14FA8C59121DA4A000C4264B /* UIViewAnimationGroup.h */, 14FA8C5A121DA4A000C4264B /* UIViewAnimationGroup.m */, - 14BF16D912E621EB007DAA01 /* UIViewBlockAnimationDelegate.h */, - 14BF16DA12E621EB007DAA01 /* UIViewBlockAnimationDelegate.m */, 14FA8C5B121DA4A000C4264B /* UIViewLayoutManager.h */, 14FA8C5C121DA4A000C4264B /* UIViewLayoutManager.m */, ); @@ -940,18 +939,14 @@ 14FA8C44121DA47500C4264B /* Private Categories */ = { isa = PBXGroup; children = ( - 14A726AF1213303400648C9B /* UIApplication+UIPrivate.h */, 145BE3201575523000C41D70 /* UIColor+UIPrivate.h */, 14A726B11213303400648C9B /* UIControl+UIPrivate.h */, - 14EEF76512DF67CF00EB7D95 /* UIEvent+UIPrivate.h */, 38615C77133A81B900841EEA /* UIFont+UIPrivate.h */, 148984A312EE278D003D4751 /* UIGestureRecognizer+UIPrivate.h */, 14A726B41213303400648C9B /* UIImage+UIPrivate.h */, 14DD1C271289B3C900DCF231 /* UIImage+UIPrivate.m */, 14A726B51213303400648C9B /* UIImageView+UIPrivate.h */, - 14EEF7A812DF6D9C00EB7D95 /* UIKey+UIPrivate.h */, - 38E523B413396B5B00E041B3 /* UINavigationBar+UIPrivate.h */, - 38E523AF1339680400E041B3 /* UINavigationItem+UIPrivate.h */, + 145D0B0417949A6800FB569B /* UINavigationItem+UIPrivate.h */, 1490AFDE1219C31C00774286 /* UIPopoverController+UIPrivate.h */, 14A726B71213303400648C9B /* UIScreen+UIPrivate.h */, 1443DF23121F0D5A00E07C4A /* UIScreenMode+UIPrivate.h */, @@ -959,7 +954,6 @@ 14A726B91213303400648C9B /* UITableViewCell+UIPrivate.h */, 14A726BA1213303400648C9B /* UITouch+UIPrivate.h */, 14A726BB1213303400648C9B /* UIView+UIPrivate.h */, - 14A726BC1213303400648C9B /* UIViewController+UIPrivate.h */, 14A726BD1213303400648C9B /* UIWindow+UIPrivate.h */, ); name = "Private Categories"; @@ -981,12 +975,10 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 789CF898133A3CD500250AB4 /* NSFetchedResultsController.h in Headers */, 78CB48D9133AB922008636DA /* UISlider.h in Headers */, 78CB48B4133AA8AF008636DA /* UISegmentedControl.h in Headers */, 14CC840611EFA8AF005988CC /* UIRoundedRectButton.h in Headers */, 78CB48BC133AADD0008636DA /* UIPickerView.h in Headers */, - 14A726D21213303400648C9B /* UIApplication+UIPrivate.h in Headers */, 14A726D41213303400648C9B /* UIControl+UIPrivate.h in Headers */, 14A726D71213303400648C9B /* UIImage+UIPrivate.h in Headers */, 14A726D81213303400648C9B /* UIImageView+UIPrivate.h in Headers */, @@ -994,7 +986,6 @@ 14A726DC1213303400648C9B /* UITableViewCell+UIPrivate.h in Headers */, 14A726DD1213303400648C9B /* UITouch+UIPrivate.h in Headers */, 14A726DE1213303400648C9B /* UIView+UIPrivate.h in Headers */, - 14A726DF1213303400648C9B /* UIViewController+UIPrivate.h in Headers */, 78CB48B0133AA536008636DA /* UITabBarItem.h in Headers */, 14A726E01213303400648C9B /* UIWindow+UIPrivate.h in Headers */, 78D533DD133A9434006F17CA /* UISearchDisplayController.h in Headers */, @@ -1032,7 +1023,6 @@ 1489859D12EE2CFF003D4751 /* UIImageAppKitIntegration.h in Headers */, 1489859E12EE2CFF003D4751 /* UIImagePickerController.h in Headers */, 148985A012EE2CFF003D4751 /* UIImageView.h in Headers */, - 148985A212EE2CFF003D4751 /* UIKey.h in Headers */, 148985A412EE2CFF003D4751 /* UIKit.h in Headers */, 148985A512EE2CFF003D4751 /* UIKitView.h in Headers */, 148985A712EE2CFF003D4751 /* UILabel.h in Headers */, @@ -1058,24 +1048,20 @@ 14F56F4412664D430045EC82 /* UIPopoverView.h in Headers */, 14CB384512689907003334AD /* UIPopoverNSWindow.h in Headers */, 14CB384912689949003334AD /* UIPopoverOverlayNSView.h in Headers */, - 1457DD3F128DDE610057A7F9 /* UITransitionView.h in Headers */, 14805F5A12A6E2AE0080C4BA /* UIScrollView+UIPrivate.h in Headers */, - 14EEF76712DF67CF00EB7D95 /* UIEvent+UIPrivate.h in Headers */, - 14EEF7A912DF6D9C00EB7D95 /* UIKey+UIPrivate.h in Headers */, - 14BF16DB12E621EB007DAA01 /* UIViewBlockAnimationDelegate.h in Headers */, 148984A512EE278D003D4751 /* UIGestureRecognizer+UIPrivate.h in Headers */, - 38E523B11339680400E041B3 /* UINavigationItem+UIPrivate.h in Headers */, 14805D4112A6B0E80080C4BA /* UINSClipView.h in Headers */, 144156DB1284A22200532FE2 /* UIToolbarButton.h in Headers */, 1426FFDD129ADEA300BD31E5 /* UIControlAction.h in Headers */, 14C0716213CF66B800B76E35 /* UIScrollWheelGestureRecognizer.h in Headers */, - 38E523B513396B5B00E041B3 /* UINavigationBar+UIPrivate.h in Headers */, + 14FE493A171C988B009C7794 /* UITextInput.h in Headers */, 14FDE99C153C9A1800A2D499 /* UIAppearance.h in Headers */, 38615C78133A81B900841EEA /* UIFont+UIPrivate.h in Headers */, 148985B312EE2CFF003D4751 /* UINavigationItem.h in Headers */, 148985B512EE2CFF003D4751 /* UINibLoading.h in Headers */, 148985B712EE2CFF003D4751 /* UIPageControl.h in Headers */, 148985B912EE2CFF003D4751 /* UIPasteboard.h in Headers */, + 148985A212EE2CFF003D4751 /* UIKey.h in Headers */, 148985BB12EE2CFF003D4751 /* UIPinchGestureRecognizer.h in Headers */, 148985BD12EE2CFF003D4751 /* UIPopoverController.h in Headers */, 148985BF12EE2CFF003D4751 /* UIProgressView.h in Headers */, @@ -1116,12 +1102,17 @@ 14D8D941135DE90A00FE639A /* UIInputController.h in Headers */, 14541DB21360D6F300C1006D /* UIPhotosAlbum.h in Headers */, 14C0715E13CF5A2400B76E35 /* UIAction.h in Headers */, - 14FDE9A5153CAECA00A2D499 /* UIAppearanceProxy.h in Headers */, - 14D796381540A5DA00C02139 /* UIAppearanceProperty.h in Headers */, 145576231541DC560029EF4D /* UIAppearanceInstance.h in Headers */, 14711394156FC83F00251B2E /* UIImageRep.h in Headers */, 145BE31D15754F2400C41D70 /* UIColorRep.h in Headers */, 145BE3211575523000C41D70 /* UIColor+UIPrivate.h in Headers */, + 14D0601717303DC100C9A7C6 /* UINSApplicationDelegate.h in Headers */, + 14BA42F217554D0200891B6D /* UITouchEvent.h in Headers */, + 14100F70175FB9C700269BBF /* UINSResponderShim.h in Headers */, + 1434E8661770F4570023F2C5 /* UIViewControllerAppKitIntegration.h in Headers */, + 145D0B0517949A6800FB569B /* UINavigationItem+UIPrivate.h in Headers */, + 14FDE9A5153CAECA00A2D499 /* UIAppearanceProxy.h in Headers */, + 14D796381540A5DA00C02139 /* UIAppearanceProperty.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1153,7 +1144,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0510; }; buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "UIKit" */; compatibilityVersion = "Xcode 3.2"; @@ -1222,7 +1213,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 789CF899133A3CD500250AB4 /* NSFetchedResultsController.m in Sources */, 78CB48B1133AA536008636DA /* UITabBarItem.m in Sources */, 78CB48AD133A9C51008636DA /* UISearchBar.m in Sources */, 14CC840711EFA8AF005988CC /* UIRoundedRectButton.m in Sources */, @@ -1243,10 +1233,8 @@ 14CB384A12689949003334AD /* UIPopoverOverlayNSView.m in Sources */, 144156DC1284A22200532FE2 /* UIToolbarButton.m in Sources */, 14DD1C281289B3C900DCF231 /* UIImage+UIPrivate.m in Sources */, - 1457DD40128DDE610057A7F9 /* UITransitionView.m in Sources */, 1426FFDE129ADEA300BD31E5 /* UIControlAction.m in Sources */, 14805D4212A6B0E80080C4BA /* UINSClipView.m in Sources */, - 14BF16DC12E621EB007DAA01 /* UIViewBlockAnimationDelegate.m in Sources */, 1489856C12EE2CFF003D4751 /* NSIndexPath+UITableView.m in Sources */, 1489856E12EE2CFF003D4751 /* UIAcceleration.m in Sources */, 1489857012EE2CFF003D4751 /* UIAccelerometer.m in Sources */, @@ -1333,6 +1321,10 @@ 14711395156FC83F00251B2E /* UIImageRep.m in Sources */, 14E20663156FE88D0040349D /* UIImageAppKitIntegration.m in Sources */, 145BE31E15754F2400C41D70 /* UIColorRep.m in Sources */, + 14FE4941171C9989009C7794 /* UITextInput.m in Sources */, + 14D0601817303DC100C9A7C6 /* UINSApplicationDelegate.m in Sources */, + 14BA42F317554D0200891B6D /* UITouchEvent.m in Sources */, + 14100F71175FB9C700269BBF /* UINSResponderShim.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1343,6 +1335,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; COPY_PHASE_STRIP = NO; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1356,7 +1349,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = UIKit; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Debug; @@ -1365,6 +1357,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_ARC = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1376,7 +1369,6 @@ INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = UIKit; SYMROOT = ../build; - VALID_ARCHS = "i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Release; @@ -1384,13 +1376,12 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; @@ -1399,13 +1390,12 @@ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; + CODE_SIGN_IDENTITY = "Developer ID Application: The Iconfactory"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; + MACOSX_DEPLOYMENT_TARGET = 10.7; PROVISIONING_PROFILE = ""; SDKROOT = macosx; }; diff --git a/UIKit/UIKit.xcodeproj/project.xcworkspace/xcshareddata/UIKit.xccheckout b/UIKit/UIKit.xcodeproj/project.xcworkspace/xcshareddata/UIKit.xccheckout new file mode 100644 index 00000000..76973da2 --- /dev/null +++ b/UIKit/UIKit.xcodeproj/project.xcworkspace/xcshareddata/UIKit.xccheckout @@ -0,0 +1,50 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + DDACB42D-640A-4EF9-AE4D-A20276EBFE16 + IDESourceControlProjectName + UIKit + IDESourceControlProjectOriginsDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk + + IDESourceControlProjectPath + UIKit/UIKit.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + ../../.. + + IDESourceControlProjectRepositoryRootDictionary + + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + svn://dev.iconfactory.net/Projects/Software + + IDESourceControlProjectURL + svn://dev.iconfactory.net/Projects/Software/UIKit/trunk/UIKit/UIKit.xcodeproj + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryBranchesRelativeLocationKey + UIKit/branches + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.subversion + IDESourceControlRepositoryTrunkRelativeLocationKey + UIKit/trunk + IDESourceControlWCCIdentifierKey + 4D4CCC13-43EF-4EE0-831F-37E84AFA83EA + IDESourceControlWCCName + UIKit + + + + diff --git a/UIKit/UIKit_Prefix.pch b/UIKit/UIKit_Prefix.pch index 73ffda54..a9ca302e 100644 --- a/UIKit/UIKit_Prefix.pch +++ b/UIKit/UIKit_Prefix.pch @@ -30,13 +30,3 @@ #ifdef __OBJC__ #import #endif - -// 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