iOS 按比例实现方块图

编程入门 行业动态 更新时间:2024-10-08 18:36:11

iOS 按比例实现<a href=https://www.elefans.com/category/jswz/34/1165691.html style=方块图"/>

iOS 按比例实现方块图

原理:二分法递归实现,就是每次“对半分”,分到只剩两个

 

上代码:SZBlockView 

@interface SZBlockView : UIView
@property (nonatomic, strong) NSArray *data;//数据源
@end#import "SZBlockView.h"
#import "SZItemView.h"@implementation SZBlockView- (instancetype)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self) {self.backgroundColor = UIColor.whiteColor;}return self;
}-(void)setData:(NSArray *)data
{_data = data;[self removeAll];for (NSString* value in data) {[self addSubNode:[value intValue]];}[self recalcLayout];
}-(void)addSubNode:(int)value
{SZItemView* item = [SZItemView new];item.value = value;[self addSubview:item];
}-(void)removeAll
{//移除所有子视图[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}-(bool)isVertical:(double)w Height:(double) h
{return w / h > 1.618;//黄金比例,可以自己根据需求修改
}-(void)recalcLayout
{if (self.subviews.count < 1) return;[self recalcSquarifiedLayout:0 Finish:self.subviews.count - 1 Area:self.bounds];
}-(void)recalcSliceLayout:(NSUInteger)nStart Finish:(NSUInteger)nFinish Area:(CGRect)rect IsVertical:(bool) bIsVertical
{NSAssert(nStart < self.subviews.count, @"nStart >= self.subviews.count");NSAssert(nFinish < self.subviews.count, @"nFinish >= self.subviews.count");if (nStart == nFinish){[self.subviews[nStart] setFrame:rect];return;}double dblTotal = [self getChildrenTotal:nStart Finish:nFinish];double x = rect.origin.x;double y = rect.origin.y;if (bIsVertical){for (NSUInteger i = nStart; i <= nFinish; i++){SZItemView* item = self.subviews[i];double cx = rect.size.width * item.value / dblTotal;CGRect rectSubNode = item.frame;rectSubNode = rect;rectSubNode.origin.x = x;if (i == nFinish) {rectSubNode.size.width = cx;}else{rectSubNode.size.width = cx-1;}item.frame = rectSubNode;x += cx;}} else{for (NSUInteger i = nStart; i <= nFinish; i++){SZItemView* item = self.subviews[i];double cy = rect.size.height * item.value / dblTotal;CGRect rectSubNode = item.frame;rectSubNode = rect;rectSubNode.origin.y = y;if (i==nFinish) {rectSubNode.size.height = cy;}else{rectSubNode.size.height = cy-1;}item.frame = rectSubNode;y += cy;}}
}-(void)recalcSquarifiedLayout:(NSUInteger)nStart Finish:(NSUInteger)nFinish Area:(CGRect) rect
{NSAssert(nStart < self.subviews.count, @"nStart >= self.subviews.count");NSAssert(nFinish < self.subviews.count, @"nFinish >= self.subviews.count");if (nStart + 2 > nFinish){return [self recalcSliceLayout:nStart Finish:nFinish Area:rect IsVertical:[self isVertical:rect.size.width Height:rect.size.height]];}double total = [self getChildrenTotal:nStart Finish:nFinish],total_left = 0.;for (NSUInteger i = nStart; i <= nFinish; i++){SZItemView* item = self.subviews[i];double pre_dt = total_left - total / 2;total_left += item.value;double dt = total_left - total / 2;if (dt > 0){if (dt + pre_dt >= 0){total_left -= item.value;i--;}if ([self isVertical:rect.size.width Height:rect.size.height]){CGRect rectLeft = rect;rectLeft.size.width = rect.size.width * total_left / total - 1;[self recalcSquarifiedLayout:nStart Finish:i Area:rectLeft];CGRect rectRight = rect;rectRight.origin.x = rectLeft.origin.x + rectLeft.size.width + 1;rectRight.size.width = rect.size.width - rectLeft.size.width - 1;[self recalcSquarifiedLayout:i + 1 Finish:nFinish Area:rectRight];} else{CGRect rectTop = rect;rectTop.size.height = rect.size.height * total_left / total - 1;[self recalcSquarifiedLayout:nStart Finish:i Area:rectTop];CGRect rectBottom = rect;rectBottom.origin.y = rectTop.origin.y + rectTop.size.height + 1;rectBottom.size.height = rect.size.height - rectTop.size.height - 1;[self recalcSquarifiedLayout:i + 1 Finish:nFinish Area:rectBottom];}return;}}//    NSAssert(false, @"unreachable");
}-(double)getChildrenTotal:(NSUInteger)nStart Finish:(NSUInteger) nFinish
{double dblTotal = 0.;for (NSUInteger i = nStart; i <= nFinish; i++){SZItemView* item = self.subviews[i];dblTotal += item.value;}return dblTotal;
}@end

SZItemView 里面的每一个小的视图

@interface SZItemView : UIView
@property (nonatomic, assign) int value;//传入要显示的值
@end#import "SZItemView.h"
@interface SZItemView ()
@property (nonatomic, strong) UILabel *valueLabel;
@end@implementation SZItemView- (instancetype)init
{self = [super init];if (self) {[self setupUI];}return self;
}
-(void)setupUI{UILabel *valueLabel = [[UILabel alloc] initWithFrame:self.frame];valueLabel.adjustsFontSizeToFitWidth = YES;self.valueLabel = valueLabel;valueLabel.textAlignment = NSTextAlignmentCenter;valueLabel.textColor = UIColor.whiteColor;[self addSubview:valueLabel];
}- (void)setValue:(int)value{_value = value;self.valueLabel.text = [NSString stringWithFormat:@"%d",value];self.backgroundColor = UIColor.orangeColor;
}
- (void)layoutSubviews{//如果用masonry布局此方法可不实现self.valueLabel.frame = self.bounds;self.valueLabel.adjustsFontSizeToFitWidth = YES;
}
@end

效果图:

更多推荐

iOS 按比例实现方块图

本文发布于:2024-02-07 09:28:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1755538.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方块图   按比例   iOS

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!