Skip to content

Commit ba8afd6

Browse files
committed
Release V1.3.9 Fix #39, #40, #41
1 parent af72e52 commit ba8afd6

17 files changed

+507
-301
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33

44
---
55

6+
## [V1.3.9](https://github.com/youngsoft/MyLinearLayout/releases/tag/1.3.9)(2017/6/12)
7+
8+
#### Fixed
9+
1. 修复了[#BUG41](https://github.com/youngsoft/MyLinearLayout/issues/41)。原因是当左右两边的子视图尺寸有重合并且高度或者宽度相等时没有将两边的占用区域进行合并,从而影响了新加入的子视图的尺寸设置。
10+
2. 修复了[#BUG40](https://github.com/youngsoft/MyLinearLayout/issues/40)。原因是当UIScrollView的contentOffset值为负数时,如果修改视图的frame值将会把contentOffset的值重置为0.这个是一个系统的特性,因此解决的方案是不修改frame而是修改bounds和center两个属性。
11+
3. 修复了[#BUG39](https://github.com/youngsoft/MyLinearLayout/issues/39)。原因是当设置视图的frame的pt值时如果pt值无法转化为有效的设备的物理像素时将会出现:**文字模糊发虚、线发虚、以及文字无法多行显示、以及当使用layer的cornerRadius时无法绘制出正确的圆形的问题**。因此解决的方案是在布局完成后设置frame时会将pt值四舍五入转化为最小的可显示的物理像素值。
12+
13+
14+
615
## [V1.3.8](https://github.com/youngsoft/MyLinearLayout/releases/tag/1.3.8)(2017/6/2)
716

817
#### Fixed

MyLayout.podspec

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
1616
#
1717

1818
s.name = "MyLayout"
19-
s.version = "1.3.8"
19+
s.version = "1.3.9"
2020
s.summary = "MyLayout is an iOS UI framework integrates the functions with Android,AutoLayout,SizeClass,HTML CSS float and flexbox,UIView UITableView."
2121

2222
s.description = <<-DESC
@@ -75,7 +75,7 @@ Pod::Spec.new do |s|
7575
# Supports git, hg, bzr, svn and HTTP.
7676
#
7777

78-
s.source = { :git => "https://github.com/youngsoft/MyLinearLayout.git", :tag => "1.3.8" }
78+
s.source = { :git => "https://github.com/youngsoft/MyLinearLayout.git", :tag => "1.3.9" }
7979

8080

8181
# ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #

MyLayout.xcodeproj/project.pbxproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@
12781278
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
12791279
PRODUCT_BUNDLE_IDENTIFIER = "com.youngsoft.$(PRODUCT_NAME:rfc1034identifier)";
12801280
PRODUCT_NAME = MyLayout;
1281-
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MyLayout.app/MyLayout";
1281+
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MyLayoutDemo.app/MyLayoutDemo";
12821282
};
12831283
name = Debug;
12841284
};
@@ -1295,7 +1295,7 @@
12951295
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
12961296
PRODUCT_BUNDLE_IDENTIFIER = "com.youngsoft.$(PRODUCT_NAME:rfc1034identifier)";
12971297
PRODUCT_NAME = MyLayout;
1298-
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MyLayout.app/MyLayout";
1298+
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MyLayoutDemo.app/MyLayoutDemo";
12991299
};
13001300
name = Release;
13011301
};

MyLayout/Lib/MyBaseLayout.m

+125-32
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,17 @@
1717
void* _myObserverContextB = (void*)20175282;
1818
void* _myObserverContextC = (void*)20175283;
1919

20+
CGFloat _myMyLayoutScale = 1.0;
21+
CGFloat _myMLayoutSizeError = 0.0;
2022

2123
@implementation UIView(MyLayoutExt)
2224

25+
+(void)load
26+
{
27+
_myMyLayoutScale = [UIScreen mainScreen].scale;
28+
_myMLayoutSizeError = (1.0 / _myMyLayoutScale + 0.0001); //误差增量。
29+
}
30+
2331

2432
-(MyLayoutPos*)topPos
2533
{
@@ -1257,7 +1265,7 @@ -(CGRect)estimateLayoutRect:(CGSize)size inSizeClass:(MySizeClass)sizeClass sbs:
12571265
if (self.cacheEstimatedRect)
12581266
_useCacheRects = YES;
12591267

1260-
return CGRectMake(0, 0, selfSize.width, selfSize.height);
1268+
return CGRectMake(0, 0, _myRoundNumber(selfSize.width), _myRoundNumber(selfSize.height));
12611269
}
12621270

12631271
//只获取计算得到尺寸,不进行真正的布局。
@@ -1374,7 +1382,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(UIView*)object chan
13741382
//只监控父视图的尺寸变换
13751383
CGRect rcOld = [change[NSKeyValueChangeOldKey] CGRectValue];
13761384
CGRect rcNew = [change[NSKeyValueChangeNewKey] CGRectValue];
1377-
if (!CGSizeEqualToSize(rcOld.size, rcNew.size))
1385+
if (!_myCGSizeEqual(rcOld.size, rcNew.size))
13781386
{
13791387
[self myUpdateLayoutRectInNoLayoutSuperview:object];
13801388
}
@@ -1789,6 +1797,7 @@ -(void)layoutSubviews
17891797
{
17901798
newSelfSize = [self calcLayoutRect:[self myCalcSizeInNoLayoutSuperview:self.superview currentSize:oldSelfSize] isEstimate:NO pHasSubLayout:nil sizeClass:sizeClass sbs:nil];
17911799
}
1800+
newSelfSize = _myRoundSize(newSelfSize);
17921801
_useCacheRects = NO;
17931802

17941803
//设置子视图的frame并还原
@@ -1811,21 +1820,24 @@ -(void)layoutSubviews
18111820
}
18121821

18131822
//这里的位置需要进行有效像素的舍入处理,否则可能出现文本框模糊,以及视图显示可能多出一条黑线的问题。
1814-
CGRect rc = sbvmyFrame.frame;
1815-
if (![sbv isKindOfClass:[MyBaseLayout class]])
1823+
//原因是当frame中的值不能有效的转化为最小可绘制的物理像素时就会出现模糊,虚化,多出黑线,以及layer处理圆角不圆的情况。
1824+
//所以这里要将frame中的点转化为有效的点。
1825+
//这里之所以讲布局子视图的转化方法和一般子视图的转化方法区分开来是因为。我们要保证布局子视图不能出现细微的重叠,因为布局子视图有边界线
1826+
//如果有边界线而又出现细微重叠的话,那么边界线将无法正常显示,因此这里做了一个特殊的处理。
1827+
CGRect rc;
1828+
if ([sbv isKindOfClass:[MyBaseLayout class]])
18161829
{
1817-
rc = _myRoundRect(rc);
1818-
}
1819-
1820-
if (CGAffineTransformIsIdentity(sbv.transform))
1821-
{
1822-
sbv.frame = rc;
1830+
rc = _myRoundRectForLayout(sbvmyFrame.frame);
18231831
}
18241832
else
18251833
{
1826-
sbv.center = CGPointMake(rc.origin.x + sbv.layer.anchorPoint.x * rc.size.width, rc.origin.y + sbv.layer.anchorPoint.y * rc.size.height);
1827-
sbv.bounds = CGRectMake(ptorigin.x, ptorigin.y, rc.size.width, rc.size.height);
1834+
rc = _myRoundRect(sbvmyFrame.frame);
18281835
}
1836+
1837+
1838+
sbv.center = CGPointMake(rc.origin.x + sbv.layer.anchorPoint.x * rc.size.width, rc.origin.y + sbv.layer.anchorPoint.y * rc.size.height);
1839+
sbv.bounds = CGRectMake(ptorigin.x, ptorigin.y, rc.size.width, rc.size.height);
1840+
18291841

18301842
}
18311843

@@ -1846,9 +1858,15 @@ -(void)layoutSubviews
18461858
[sbvmyFrame reset];
18471859
}
18481860

1849-
//调整自身
1850-
if (!CGSizeEqualToSize(oldSelfSize,newSelfSize) && newSelfSize.width != CGFLOAT_MAX)
1861+
1862+
if (newSelfSize.width != CGFLOAT_MAX && (lsc.wrapContentWidth || lsc.wrapContentHeight))
18511863
{
1864+
1865+
//因为布局子视图的新老尺寸计算在上面有两种不同的方法,因此这里需要考虑两种计算的误差值,而这两种计算的误差值是不超过1/屏幕精度的。
1866+
//因此我们认为当二者的值超过误差时我们才认为有尺寸变化。
1867+
BOOL isWidthAlter = fabs(newSelfSize.width - oldSelfSize.width) > _myMLayoutSizeError;
1868+
BOOL isHeightAlter = fabs(newSelfSize.height - oldSelfSize.height) > _myMLayoutSizeError;
1869+
18521870
//如果父视图也是布局视图,并且自己隐藏则不调整自身的尺寸和位置。
18531871
BOOL isAdjustSelf = YES;
18541872
if (self.superview != nil && [self.superview isKindOfClass:[MyBaseLayout class]])
@@ -1857,7 +1875,7 @@ -(void)layoutSubviews
18571875
if ([supl myIsNoLayoutSubview:self])
18581876
isAdjustSelf = NO;
18591877
}
1860-
if (isAdjustSelf)
1878+
if (isAdjustSelf && (isWidthAlter || isHeightAlter))
18611879
{
18621880

18631881
if (newSelfSize.width < 0)
@@ -1872,13 +1890,36 @@ -(void)layoutSubviews
18721890

18731891
if (CGAffineTransformIsIdentity(self.transform))
18741892
{
1875-
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, newSelfSize.width, newSelfSize.height);
1893+
CGRect currentFrame = self.frame;
1894+
if (isWidthAlter && lsc.wrapContentWidth)
1895+
currentFrame.size.width = newSelfSize.width;
1896+
1897+
if (isHeightAlter && lsc.wrapContentHeight)
1898+
currentFrame.size.height = newSelfSize.height;
1899+
1900+
self.frame = currentFrame;
18761901
}
18771902
else
18781903
{
1879-
self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, newSelfSize.width, newSelfSize.height);
1880-
self.center = CGPointMake(self.center.x + (newSelfSize.width - oldSelfSize.width) * self.layer.anchorPoint.x, self.center.y + (newSelfSize.height - oldSelfSize.height) * self.layer.anchorPoint.y);
1881-
}
1904+
CGRect currentBounds = self.bounds;
1905+
CGPoint currentCenter = self.center;
1906+
1907+
if (isWidthAlter && lsc.wrapContentWidth)
1908+
{
1909+
currentBounds.size.width = newSelfSize.width;
1910+
currentCenter.x += (newSelfSize.width - oldSelfSize.width) * self.layer.anchorPoint.x;
1911+
}
1912+
1913+
if (isHeightAlter && lsc.wrapContentHeight)
1914+
{
1915+
currentBounds.size.height = newSelfSize.height;
1916+
currentCenter.y += (newSelfSize.height - oldSelfSize.height) * self.layer.anchorPoint.y;
1917+
}
1918+
1919+
self.bounds = currentBounds;
1920+
self.center = currentCenter;
1921+
1922+
}
18821923
}
18831924
}
18841925

@@ -1933,7 +1974,7 @@ -(void)layoutSubviews
19331974
centerPonintSelf.x = rectSuper.size.width - centerPonintSelf.x;
19341975

19351976
//如果有变化则只调整自己的center。而不变化
1936-
if (!CGPointEqualToPoint(self.center, centerPonintSelf))
1977+
if (!_myCGPointEqual(self.center, centerPonintSelf))
19371978
{
19381979
self.center = centerPonintSelf;
19391980
}
@@ -1963,7 +2004,7 @@ -(void)layoutSubviews
19632004
superCenter.x += (superBounds.size.width - supv.bounds.size.width) * supv.layer.anchorPoint.x;
19642005
}
19652006

1966-
if (!CGRectEqualToRect(supv.bounds, superBounds))
2007+
if (!_myCGRectEqual(supv.bounds, superBounds))
19672008
{
19682009
supv.center = superCenter;
19692010
supv.bounds = superBounds;
@@ -2434,7 +2475,8 @@ -(BOOL)myUpdateLayoutRectInNoLayoutSuperview:(UIView*)newSuperview
24342475
if ([MyBaseLayout isRTL])
24352476
rectSelf.origin.x = rectSuper.size.width - rectSelf.origin.x - rectSelf.size.width;
24362477

2437-
if (!CGRectEqualToRect(rectSelf, oldRectSelf))
2478+
rectSelf = _myRoundRect(rectSelf);
2479+
if (!_myCGRectEqual(rectSelf, oldRectSelf))
24382480
{
24392481
if (rectSelf.size.width < 0)
24402482
{
@@ -3339,6 +3381,7 @@ -(void)layoutSublayersOfLayer:(CAShapeLayer *)layer
33393381
layerRect = CGRectMake(self.bottomBorderline.headIndent, layoutSize.height - self.bottomBorderline.thick / scale - self.bottomBorderline.offset, layoutSize.width - self.bottomBorderline.headIndent - self.bottomBorderline.tailIndent, self.bottomBorderline.thick /scale);
33403382
fromPoint = CGPointMake(0, 0);
33413383
toPoint = CGPointMake(layerRect.size.width, 0);
3384+
33423385
}
33433386
else
33443387
{
@@ -3354,7 +3397,9 @@ -(void)layoutSublayersOfLayer:(CAShapeLayer *)layer
33543397
}
33553398

33563399
//把动画效果取消。
3357-
if (!CGRectEqualToRect(layer.frame, layerRect))
3400+
3401+
3402+
if (!_myCGRectEqual(layer.frame, layerRect))
33583403
{
33593404
if (layer.lineDashPhase == 0)
33603405
{
@@ -3500,28 +3545,76 @@ BOOL _myCGFloatGreatOrEqual(CGFloat f1, CGFloat f2)
35003545
#endif
35013546
}
35023547

3548+
BOOL _myCGSizeEqual(CGSize sz1, CGSize sz2)
3549+
{
3550+
return _myCGFloatEqual(sz1.width, sz2.width) && _myCGFloatEqual(sz1.height, sz2.height);
3551+
}
3552+
3553+
BOOL _myCGPointEqual(CGPoint pt1, CGPoint pt2)
3554+
{
3555+
return _myCGFloatEqual(pt1.x, pt2.x) && _myCGFloatEqual(pt1.y, pt2.y);
3556+
}
3557+
3558+
BOOL _myCGRectEqual(CGRect rect1, CGRect rect2)
3559+
{
3560+
return _myCGSizeEqual(rect1.size, rect2.size) && _myCGPointEqual(rect1.origin, rect2.origin);
3561+
}
3562+
3563+
35033564
CGFloat _myRoundNumber(CGFloat f)
35043565
{
3505-
if (f == CGFLOAT_MAX)
3566+
if (f == 0 || f == CGFLOAT_MAX || f == -CGFLOAT_MAX)
35063567
return f;
35073568

3508-
static CGFloat scale;
3509-
scale = [UIScreen mainScreen].scale;
3510-
static CGFloat inc;
3511-
inc = 0.5/scale;
3569+
int fi = (int)f;
3570+
if (f == fi)
3571+
return fi;
3572+
3573+
//按精度四舍五入
3574+
//正确的算法应该是。x = 0; y = 0; 0<x<0.5 y = 0; x = 0.5 y = 0.5; 0.5<x<1 y = 0.5; x=1 y = 1;
35123575

3513-
f += inc;
3514-
f *= scale;
3515-
return floor(f) / scale;
3576+
if (f < 0)
3577+
{
3578+
return ceil(f * _myMyLayoutScale) / _myMyLayoutScale;
3579+
}
3580+
else
3581+
{
3582+
return floor(f *_myMyLayoutScale) / _myMyLayoutScale;
3583+
}
3584+
35163585
}
35173586

3587+
CGRect _myRoundRectForLayout(CGRect rect)
3588+
{
3589+
CGFloat x1 = rect.origin.x;
3590+
CGFloat y1 = rect.origin.y;
3591+
CGFloat w1 = rect.size.width;
3592+
CGFloat h1 = rect.size.height;
3593+
3594+
rect.origin.x = _myRoundNumber(x1);
3595+
rect.origin.y = _myRoundNumber(y1);
3596+
3597+
CGFloat mx = _myRoundNumber(x1 + w1);
3598+
CGFloat my = _myRoundNumber(y1 + h1);
3599+
3600+
rect.size.width = mx - rect.origin.x;
3601+
rect.size.height = my - rect.origin.y;
3602+
3603+
return rect;
3604+
3605+
}
3606+
3607+
3608+
35183609
CGRect _myRoundRect(CGRect rect)
35193610
{
3520-
rect.origin.x = _myRoundNumber(rect.origin.x);
3611+
rect.origin.x = _myRoundNumber(rect.origin.x);
35213612
rect.origin.y = _myRoundNumber(rect.origin.y);
35223613
rect.size.width = _myRoundNumber(rect.size.width);
35233614
rect.size.height = _myRoundNumber(rect.size.height);
3615+
35243616
return rect;
3617+
35253618
}
35263619

35273620
CGSize _myRoundSize(CGSize size)

0 commit comments

Comments
 (0)