Move files around

This commit is contained in:
Rui Marinho
2016-12-16 14:09:39 +00:00
parent 57b042feb1
commit cb44a9f5a2
291 changed files with 25201 additions and 1724 deletions

View File

@@ -96,6 +96,29 @@
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(514,21), containerSize), @"Size is actually %@", NSStringFromCGSize(containerSize));
}
- (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
[container yg_setAlignItems:YGAlignFlexStart];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = @"This is a short text.";
label.numberOfLines = 1;
[label yg_setUsesYoga:YES];
[container addSubview:label];
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(146,21), label.bounds.size), @"Size is actually %@", NSStringFromCGSize(label.bounds.size));
label.text = @"This is a slightly longer text.";
[label yg_markDirty];
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(213,21), label.bounds.size), @"Size is actually %@", NSStringFromCGSize(label.bounds.size));
}
- (void)testFrameAndOriginPlacement
{
const CGSize containerSize = CGSizeMake(320, 50);
@@ -268,4 +291,97 @@
}
}
- (void)testyg_isLeafFlag
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertTrue(view.yg_isLeaf);
for (int i=0; i<10; i++) {
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
[view addSubview:subview];
}
XCTAssertTrue(view.yg_isLeaf);
[view yg_setUsesYoga:YES];
[view yg_setWidth:50.0];
XCTAssertTrue(view.yg_isLeaf);
UIView *const subview = view.subviews[0];
[subview yg_setUsesYoga:YES];
[subview yg_setWidth:50.0];
XCTAssertFalse(view.yg_isLeaf);
}
- (void)testThatWeCorrectlyAttachNestedViews
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionColumn];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[subview1 yg_setWidth:100];
[subview1 yg_setFlexGrow:1];
[subview1 yg_setFlexDirection:YGFlexDirectionColumn];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview2 yg_setWidth:150];
[subview2 yg_setFlexGrow:1];
[subview2 yg_setFlexDirection:YGFlexDirectionColumn];
[container addSubview:subview2];
for (UIView *view in @[subview1, subview2]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
[someView yg_setUsesYoga:YES];
[someView yg_setFlexGrow:1];
[view addSubview:someView];
}
[container yg_applyLayout];
// Add the same amount of new views, reapply layout.
for (UIView *view in @[subview1, subview2]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
[someView yg_setUsesYoga:YES];
[someView yg_setFlexGrow:1];
[view addSubview:someView];
}
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 25), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size));
for (UIView *subview in subview1.subviews) {
const CGSize subviewSize = subview.bounds.size;
XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subviewSize));
XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width));
}
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 25), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size));
for (UIView *subview in subview2.subviews) {
const CGSize subviewSize = subview.bounds.size;
XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subview.bounds.size));
XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width));
}
}
- (void)testThatANonLeafNodeCanBecomeALeafNode
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
[container yg_setUsesYoga:YES];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview1 addSubview:subview2];
[container yg_applyLayout];
[subview2 removeFromSuperview];
[container yg_applyLayout];
}
@end

View File

@@ -30,6 +30,7 @@
- (void)yg_setAlignSelf:(YGAlign)alignSelf;
- (void)yg_setPositionType:(YGPositionType)positionType;
- (void)yg_setFlexWrap:(YGWrap)flexWrap;
- (void)yg_setOverflow:(YGOverflow)overflow;
- (void)yg_setFlexGrow:(CGFloat)flexGrow;
- (void)yg_setFlexShrink:(CGFloat)flexShrink;
@@ -69,4 +70,14 @@
*/
- (NSUInteger)yg_numberOfChildren;
/**
Return a BOOL indiciating whether or not we this node contains any subviews that are included in Yoga's layout.
*/
- (BOOL)yg_isLeaf;
/**
Mark that a view's layout needs to be recalculated. Only works for leaf views.
*/
- (void)yg_markDirty;
@end

View File

@@ -11,6 +11,8 @@
#import <objc/runtime.h>
static const void *kYGNodeBridgeAssociatedKey = &kYGNodeBridgeAssociatedKey;
@interface YGNodeBridge : NSObject
@property (nonatomic, assign, readonly) YGNodeRef cnode;
@end
@@ -39,6 +41,14 @@
@implementation UIView (Yoga)
- (void)yg_markDirty
{
YGNodeBridge *const bridge = objc_getAssociatedObject(self, kYGNodeBridgeAssociatedKey);
if (bridge != nil && [self yg_isLeaf]) {
YGNodeMarkDirty(bridge.cnode);
}
}
- (BOOL)yg_usesYoga
{
NSNumber *usesYoga = objc_getAssociatedObject(self, @selector(yg_usesYoga));
@@ -56,6 +66,20 @@
return YGNodeGetChildCount([self ygNode]);
}
- (BOOL)yg_isLeaf
{
NSAssert([NSThread isMainThread], @"This method must be called on the main thread.");
if ([self yg_usesYoga]) {
for (UIView *subview in self.subviews) {
if ([subview yg_usesYoga] && [subview yg_includeInLayout]) {
return NO;
}
}
}
return YES;
}
#pragma mark - Setters
- (void)yg_setIncludeInLayout:(BOOL)includeInLayout
@@ -116,6 +140,11 @@
YGNodeStyleSetFlexWrap([self ygNode], flexWrap);
}
- (void)yg_setOverflow:(YGOverflow)overflow
{
YGNodeStyleSetOverflow([self ygNode], overflow);
}
- (void)yg_setFlexGrow:(CGFloat)flexGrow
{
YGNodeStyleSetFlexGrow([self ygNode], flexGrow);
@@ -207,13 +236,12 @@
- (YGNodeRef)ygNode
{
YGNodeBridge *node = objc_getAssociatedObject(self, @selector(ygNode));
YGNodeBridge *node = objc_getAssociatedObject(self, kYGNodeBridgeAssociatedKey);
if (!node) {
node = [YGNodeBridge new];
YGNodeSetContext(node.cnode, (__bridge void *) self);
objc_setAssociatedObject(self, @selector(ygNode), node, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, kYGNodeBridgeAssociatedKey, node, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return node.cnode;
}
@@ -276,17 +304,32 @@ static CGFloat YGSanitizeMeasurement(
return result;
}
static void YGAttachNodesFromViewHierachy(UIView *view) {
YGNodeRef node = [view ygNode];
static BOOL YGNodeHasExactSameChildren(const YGNodeRef node, NSArray<UIView *> *subviews)
{
if (YGNodeGetChildCount(node) != subviews.count) {
return NO;
}
for (int i=0; i<subviews.count; i++) {
if (YGNodeGetChild(node, i) != subviews[i].ygNode) {
return NO;
}
}
return YES;
}
static void YGAttachNodesFromViewHierachy(UIView *const view)
{
const YGNodeRef node = [view ygNode];
// Only leaf nodes should have a measure function
if (![view yg_usesYoga] || view.subviews.count == 0) {
YGNodeSetMeasureFunc(node, YGMeasureView);
if (view.yg_isLeaf) {
YGRemoveAllChildren(node);
YGNodeSetMeasureFunc(node, YGMeasureView);
} else {
YGNodeSetMeasureFunc(node, NULL);
// Create a list of all the subviews that we are going to use for layout.
NSMutableArray<UIView *> *subviewsToInclude = [[NSMutableArray alloc] initWithCapacity:view.subviews.count];
for (UIView *subview in view.subviews) {
if ([subview yg_includeInLayout]) {
@@ -294,26 +337,15 @@ static void YGAttachNodesFromViewHierachy(UIView *view) {
}
}
BOOL shouldReconstructChildList = NO;
if (YGNodeGetChildCount(node) != subviewsToInclude.count) {
shouldReconstructChildList = YES;
} else {
for (int i = 0; i < subviewsToInclude.count; i++) {
if (YGNodeGetChild(node, i) != [subviewsToInclude[i] ygNode]) {
shouldReconstructChildList = YES;
break;
if (!YGNodeHasExactSameChildren(node, subviewsToInclude)) {
YGRemoveAllChildren(node);
for (int i=0; i<subviewsToInclude.count; i++) {
YGNodeInsertChild(node, [subviewsToInclude[i] ygNode], i);
}
}
}
if (shouldReconstructChildList) {
YGRemoveAllChildren(node);
for (int i = 0 ; i < subviewsToInclude.count; i++) {
UIView *const subview = subviewsToInclude[i];
YGNodeInsertChild(node, [subview ygNode], i);
for (UIView *const subview in subviewsToInclude) {
YGAttachNodesFromViewHierachy(subview);
}
}
}
}
@@ -340,7 +372,8 @@ static CGFloat YGRoundPixelValue(CGFloat value)
return round(value * scale) / scale;
}
static void YGApplyLayoutToViewHierarchy(UIView *view) {
static void YGApplyLayoutToViewHierarchy(UIView *view)
{
NSCAssert([NSThread isMainThread], @"Framesetting should only be done on the main thread.");
if (![view yg_includeInLayout]) {
return;
@@ -368,9 +401,8 @@ static void YGApplyLayoutToViewHierarchy(UIView *view) {
},
};
const BOOL isLeaf = ![view yg_usesYoga] || view.subviews.count == 0;
if (!isLeaf) {
for (NSUInteger i = 0; i < view.subviews.count; i++) {
if (!view.yg_isLeaf) {
for (NSUInteger i=0; i<view.subviews.count; i++) {
YGApplyLayoutToViewHierarchy(view.subviews[i]);
}
}

View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13687D421DF8748300E7C260"
BuildableName = "YogaKitSample.app"
BlueprintName = "YogaKitSample"
ReferencedContainer = "container:YogaKitSample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>YogaKitSample.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>13687D421DF8748300E7C260</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>