Ios 居中和大小在运行时和方向更改期间调整子视图
这是我在设置一些Ios 居中和大小在运行时和方向更改期间调整子视图,ios,uiview,subviews,sizetofit,Ios,Uiview,Subviews,Sizetofit,这是我在设置一些UIViews和子视图时遇到的几个问题中的第一个。我有一个ui视图,它在运行时动态定位在屏幕上。该UIView(主视图)包含另一个UIView(子视图),它封装了UIImageView和UILabel。以下是我对这种安排的要求: 当设备旋转时,子视图必须保持在主视图的中心位置 ui标签中的文本可以很长也可以很短,带有图像和文本的子视图必须仍然居中 我希望避免将UIView子类化以处理此场景,我还希望避免在willRotateToInterfaceOrientation中使用任何帧
UIView
s和子视图时遇到的几个问题中的第一个。我有一个ui视图
,它在运行时动态定位在屏幕上。该UIView
(主视图)包含另一个UIView
(子视图),它封装了UIImageView
和UILabel
。以下是我对这种安排的要求:
ui标签
中的文本可以很长也可以很短,带有图像和文本的子视图必须仍然居中AutoResizingTask
设置来处理所有这些,如果可能的话,还可以使用一些强制调整大小的代码autoresizingMask
属性已按此方式设置
(主视图):灵活的上页边距、灵活的左页边距、灵活的右页边距、灵活的宽度ui视图
(子项):灵活的上边距、灵活的下边距、灵活的左边距、灵活的右边距、灵活的宽度、灵活的高度。(所有模式,无模式除外)ui视图
:灵活的右页边距UIImageView
:灵活的右页边距ui标签
UIView
的背景比该视图略暗,而UILabel
的背景更暗。我给它们上色,以便在应用程序响应旋转时看到它们的边界
我很清楚:
- 它不是居中的,而是
- 将文本从I.B中的默认值从“此映射范围中没有数据”更改为“Test1123”后,标签将正确收缩
- 它仍然没有居中,并且可能在旋转之前处于其原始帧原点
- UIView(子视图)已扩展,以在不应填充的情况下填充更多屏幕
- UIView(主视图)已正确扩展以填充屏幕宽度
ShowNodeDataStatusView
:
// Assuming
#define kStatusViewHeight 20
- (void)showNoDataStatusView {
if (!self.noDataStatusView.superview) {
self.noDataStatusView.frame = CGRectMake(self.mapView.frame.origin.x,
self.mapView.frame.origin.y,
self.mapView.frame.size.width,
kStatusViewHeight);
self.noDataStatusView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bgRedStatus.png"]];
// Position the label view in the center
self.noDataStatusLabelView.center = CGPointMake(self.noDataStatusView.frame.size.width/2,
self.noDataStatusView.frame.size.height/2);
// Test different text
self.noDataStatusLabel.text = @"Testing, 123.";
// Size to fit label
[self.noDataStatusLabel sizeToFit];
// Test the status label view resizing
[self.noDataStatusLabelView resizeToFitSubviews];
// Add view as subview
[self.view addSubview:self.noDataStatusView];
}
}
请注意以下事项:
是我在发现UIView不会自动调整大小以适应其子视图时放置在UIView上的一个类别,即使您调用resizeToFitSubviews
,并解释了这个问题。请参见下面的类别代码sizeToFit
- 我曾考虑过创建一个UIView子类来处理所有这些逻辑,但这似乎有些过分。在I.B.安排这个应该很简单吧
- 我已尝试设置书中的每个调整大小掩码设置,以及调整标签和视图的调整顺序以及主视图作为子视图添加的点。我每次都得到奇怪的结果,似乎什么都不起作用
-(void)resizeToFitSubviews
{
float width = 0;
float height = 0;
// Loop through subviews to determine max height/width
for (UIView *v in [self subviews]) {
float fw = v.frame.origin.x + v.frame.size.width;
float fh = v.frame.origin.y + v.frame.size.height;
width = MAX(fw, width);
height = MAX(fh, height);
}
[self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, width, height)];
}
我想知道的是为什么UIView
(子视图)的superview添加到视图层次结构后没有正确居中。它看起来像是得到了正确的宽度,但不知何故保留了它在I.B.中的框架,当标签读到“此地图范围中没有数据”时
我还想知道为什么在设备旋转后它没有居中,以及我在这里采用的方法是否明智。也许这是我遇到的其他问题的原因。如有任何UIView布局帮助,将不胜感激
谢谢 如果你能够瞄准iOS 6,你可以使用新的自动布局功能使其更易于管理-我一直在阅读Ray Wenderlich的一篇文章,它似乎非常适合解决你看到的问题。这里的问题是我的
UIView
(master)设备旋转时不会自动布局其子视图,用于定位图像和内部的“弹簧和支柱”布局方法效率低下。我通过做两件事解决了这个问题
UIView
(子)实例,只剩下UIView
(主)和内部的UILabel
和UIImageView
StatusView
的UIView
子类,并在其中实现了layoutSubviews
方法。在其构造函数中,我添加了一个UIImageView
和UILabel
并动态定位它们。首先根据文本的大小定位ui标签
,然后将ui图像视图
放置在标签的左侧并垂直居中。就这样。在layoutSubviews
中,我确保为新帧调整元素的位置#import <UIKit/UIKit.h>
typedef enum {
StatusViewRecordCountType = 0,
StatusViewReachedMaxRecordCountType = 1,
StatusViewZoomInType = 2,
StatusViewConnectionLostType = 3,
StatusViewConnectionFoundType = 4,
StatusViewNoDataFoundType = 5,
StatusViewGeographyIntersectionsType = 6,
StatusViewRetreivingRecordsType = 7
} StatusViewType;
@interface StatusView : UIView
@property (strong, nonatomic) NSString *statusMessage;
@property (nonatomic) StatusViewType statusViewType;
- (id)initWithFrame:(CGRect)frame message:(NSString*)message type:(StatusViewType)type;
@end
#import "StatusView.h"
#define kConstrainSizeWidthOffset 10
#define kImageBufferWidth 15
@interface StatusView ()
@property (nonatomic, strong) UILabel *statusMessageLabel;
@property (nonatomic, strong) UIFont *statusMessageFont;
@property (nonatomic, strong) UIImage *statusImage;
@property (nonatomic, strong) UIImageView *statusImageView;
@end
@implementation StatusView
@synthesize statusMessageLabel = _statusMessageLabel;
@synthesize statusMessageFont = _statusMessageFont;
@synthesize statusImageView = _statusImageView;
@synthesize statusMessage = _statusMessage;
@synthesize statusViewType = _statusViewType;
@synthesize statusImage = _statusImage;
- (id)initWithFrame:(CGRect)frame message:(NSString *)message type:(StatusViewType)type {
self = [super initWithFrame:frame];
if (self) {
if (message != nil) {
_statusMessage = message;
_statusMessageFont = [UIFont fontWithName:@"Avenir-Roman" size:15.0];
CGSize constrainSize = CGSizeMake(self.frame.size.width - kImageBufferWidth - kConstrainSizeWidthOffset, self.frame.size.height);
// Find the size appropriate for this message
CGSize messageSize = [_statusMessage sizeWithFont:_statusMessageFont constrainedToSize:constrainSize];
// Create label and position at center of status view
CGRect labelFrame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
messageSize.width,
messageSize.height);
_statusMessageLabel = [[UILabel alloc] initWithFrame:labelFrame];
_statusMessageLabel.backgroundColor = [UIColor clearColor];
_statusMessageLabel.textColor = [UIColor whiteColor];
_statusMessageLabel.font = _statusMessageFont;
// Set shadow and color
_statusMessageLabel.shadowOffset = CGSizeMake(0, 1);
_statusMessageLabel.shadowColor = [UIColor blackColor];
// Center the label
CGPoint centerPoint = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
_statusMessageLabel.center = centerPoint;
// Gets rid of fuzziness
_statusMessageLabel.frame = CGRectIntegral(_statusMessageLabel.frame);
// Flex both the width and height as well as left and right margins
_statusMessageLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
// Set label text
_statusMessageLabel.text = _statusMessage;
[self addSubview:_statusMessageLabel];
}
self.statusViewType = type;
if (_statusImage != nil) {
// Create image view
_statusImageView = [[UIImageView alloc] initWithImage:_statusImage];
// Vertically center the image
CGPoint centerPoint = CGPointMake(_statusMessageLabel.frame.origin.x - kImageBufferWidth,
self.frame.size.height / 2);
_statusImageView.center = centerPoint;
[self addSubview:_statusImageView];
}
}
return self;
}
- (void)layoutSubviews {
CGSize constrainSize = CGSizeMake(self.frame.size.width - kImageBufferWidth - kConstrainSizeWidthOffset, self.frame.size.height);
// Find the size appropriate for this message
CGSize messageSize = [_statusMessage sizeWithFont:_statusMessageFont constrainedToSize:constrainSize];
// Create label and position at center of status view
CGRect labelFrame = CGRectMake(self.frame.origin.x,
self.frame.origin.y,
messageSize.width,
messageSize.height);
_statusMessageLabel.frame = labelFrame;
// Center the label
CGPoint centerPoint = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
_statusMessageLabel.center = centerPoint;
// Gets rid of fuzziness
_statusMessageLabel.frame = CGRectIntegral(_statusMessageLabel.frame);
if (_statusImageView != nil) {
// Vertically center the image
CGPoint centerPoint = CGPointMake(_statusMessageLabel.frame.origin.x - kImageBufferWidth,
self.frame.size.height / 2);
_statusImageView.center = centerPoint;
}
}
#pragma mark - Custom setters
- (void)setStatusMessage:(NSString *)message {
if (_statusMessage == message) return;
_statusMessage = message;
_statusMessageLabel.text = _statusMessage;
// Force layout of subviews
[self setNeedsLayout];
[self layoutIfNeeded];
}
- (void)setStatusViewType:(StatusViewType)statusViewType {
_statusViewType = statusViewType;
UIColor *bgColor = nil;
switch (_statusViewType) {
// Changes background and image based on type
}
self.backgroundColor = bgColor;
if (_statusImageView != nil) {
_statusImageView.image = _statusImage;
}
}
@end
CGRect statusFrame = CGRectMake(self.mapView.frame.origin.x,
self.mapView.frame.origin.y,
self.mapView.frame.size.width,
kStatusViewHeight);
self.staticStatusView = [[StatusView alloc] initWithFrame:statusFrame message:@"600 records found :)" type:StatusViewRecordCountType];
self.staticStatusView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self.view addSubview:self.staticStatusView];
self.staticStatusView.statusMessage = @"No data was found here";
self.staticStatusView.statusViewType = StatusViewNoDataFoundType;