From e098e138842e86fc0d411dfb8afc0eca47880ce6 Mon Sep 17 00:00:00 2001 From: Justin Pasqualini Date: Fri, 12 Dec 2014 15:47:31 -0800 Subject: [PATCH] Setting a node's background color shouldn't require calling setNeedsDisplay explicitly --- AsyncDisplayKit.xcodeproj/project.pbxproj | 4 ++++ .../Private/ASDisplayNode+UIViewBridge.mm | 18 +++++++++++++-- Base/ASEqualityHelpers.h | 22 +++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 Base/ASEqualityHelpers.h diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index d05a5731f0..9fdb19ca14 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -134,6 +134,7 @@ 05A6D05A19D0EB64002DD95E /* ASDealloc2MainObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 05A6D05B19D0EB64002DD95E /* ASDealloc2MainObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */; }; 3C9C128519E616EF00E942A0 /* ASTableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -268,6 +269,7 @@ 05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASDealloc2MainObject.h; path = ../Details/ASDealloc2MainObject.h; sourceTree = ""; }; 05A6D05919D0EB64002DD95E /* ASDealloc2MainObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASDealloc2MainObject.m; path = ../Details/ASDealloc2MainObject.m; sourceTree = ""; }; 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = ""; }; + 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = ""; }; 3C9C128419E616EF00E942A0 /* ASTableViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewTests.m; sourceTree = ""; }; 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = ""; }; AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = ""; }; @@ -497,6 +499,7 @@ 0516FA3A1A15563400B4EBED /* ASAvailability.h */, 058D0A44195D058D00B7D73C /* ASBaseDefines.h */, 058D0A45195D058D00B7D73C /* ASDisplayNodeExtraIvars.h */, + 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */, 0516FA3B1A15563400B4EBED /* ASLog.h */, ); path = Base; @@ -524,6 +527,7 @@ 058D0A48195D05CB00B7D73C /* ASControlNode.m in Headers */, 058D0A49195D05CB00B7D73C /* ASControlNode+Subclasses.h in Headers */, 058D0A4A195D05CB00B7D73C /* ASDisplayNode.h in Headers */, + 1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */, 058D0A4B195D05CB00B7D73C /* ASDisplayNode.mm in Headers */, 058D0A4C195D05CB00B7D73C /* ASDisplayNode+Subclasses.h in Headers */, 058D0A4D195D05CB00B7D73C /* ASDisplayNodeExtras.h in Headers */, diff --git a/AsyncDisplayKit/Private/ASDisplayNode+UIViewBridge.mm b/AsyncDisplayKit/Private/ASDisplayNode+UIViewBridge.mm index a7f7be98a0..51f865dffd 100644 --- a/AsyncDisplayKit/Private/ASDisplayNode+UIViewBridge.mm +++ b/AsyncDisplayKit/Private/ASDisplayNode+UIViewBridge.mm @@ -11,6 +11,7 @@ #import "ASAssert.h" #import "ASDisplayNode+Subclasses.h" #import "ASDisplayNodeInternal.h" +#import "ASEqualityHelpers.h" /** * The following macros are conveniences to help in the common tasks related to the bridging that ASDisplayNode does to UIView and CALayer. @@ -179,8 +180,14 @@ - (void)setOpaque:(BOOL)newOpaque { + BOOL prevOpaque = self.opaque; + _bridge_prologue; _setToLayer(opaque, newOpaque); + + if (prevOpaque != newOpaque) { + [self setNeedsDisplay]; + } } - (BOOL)isUserInteractionEnabled @@ -370,10 +377,17 @@ return [UIColor colorWithCGColor:_getFromLayer(backgroundColor)]; } -- (void)setBackgroundColor:(UIColor *)backgroundColor +- (void)setBackgroundColor:(UIColor *)newBackgroundColor { + UIColor *prevBackgroundColor = self.backgroundColor; + _bridge_prologue; - _setToLayer(backgroundColor, backgroundColor.CGColor); + _setToLayer(backgroundColor, newBackgroundColor.CGColor); + + // Note: This check assumes that the colors are within the same color space. + if (!ASObjectIsEqual(prevBackgroundColor, newBackgroundColor)) { + [self setNeedsDisplay]; + } } - (UIColor *)tintColor diff --git a/Base/ASEqualityHelpers.h b/Base/ASEqualityHelpers.h new file mode 100644 index 0000000000..84a4658db8 --- /dev/null +++ b/Base/ASEqualityHelpers.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "ASBaseDefines.h" + +/** + @abstract Correctly equates two objects, including cases where both objects are nil. The latter is a case where `isEqual:` fails. + @param obj The first object in the comparison. Can be nil. + @param obj The second object in the comparison. Can be nil. + @result YES if the objects are equal, including cases where both object are nil. + */ +ASDISPLAYNODE_INLINE BOOL ASObjectIsEqual(id obj, id otherObj) +{ + if (obj == otherObj) + return YES; + return [obj isEqual:otherObj]; +}