赞
踩
暑假第一周留校学习,对于ZARA进行了仿写,在仿写的过程之中,还是遇到了一些问题,此文章就是对在仿写过程之中遇到问题及其解决方案的总结,并且对自己仿写的内容进行展示。
先是在布局我的主页面的时候。使用自动布局去布局scrollView
,我发现scrollView
似乎进行布局之后并不会把scrollview给布局到主页面的时候,当时遇到这个问题,找不到问题发生的原因,以为是scrollView
无法进行自动布局,所以直接使用frame对布局进行赋值,也算是将问题解决了。
但是在编写第二个菜单页面的时候,将scrollView
和segementView
结合的时候,又是遇到这个问题了,但是这次就找到了问题所在的地方。
在程序之中 viewDidLoad
我将所有控件都进行布局,包括对scrollView
之中的图片进行添加,代码如下:
#import "JCFourth.h" @interface JCFourth ()<UIScrollViewDelegate> @property (nonatomic, strong) UISegmentedControl *segmentedControl; @property (nonatomic, strong) UIScrollView *scrollView; @property (nonatomic, strong) NSArray *titles; @property (nonatomic, strong) NSMutableArray *imageViews; @property (nonatomic, assign) NSInteger currentIndex; @property (nonatomic, strong) UIView *lineView; @end @implementation JCFourth - (void)viewDidLoad { [super viewDidLoad]; self.titles = @[@"女士", @"男士", @"儿童", @"HOME", @"香水"]; self.currentIndex = 0; self.imageViews = [NSMutableArray array]; [self setUpSegmentedControl]; [self setUpScrollView]; [self setUpLine]; [self configureImages]; } - (void)setUpLine { self.lineView = [[UIView alloc] initWithFrame:CGRectZero]; self.lineView.backgroundColor = [UIColor blackColor]; self.lineView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:self.lineView]; [NSLayoutConstraint activateConstraints:@[ [self.lineView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], [self.lineView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], [self.lineView.topAnchor constraintEqualToAnchor:self.segmentedControl.bottomAnchor], [self.lineView.heightAnchor constraintEqualToConstant:1] ]]; } - (void)setUpSegmentedControl { self.segmentedControl = [[UISegmentedControl alloc] initWithItems:self.titles]; self.segmentedControl.translatesAutoresizingMaskIntoConstraints = NO; self.segmentedControl.selectedSegmentIndex = 0; [self.segmentedControl addTarget:self action:@selector(segmentChanged:) forControlEvents:UIControlEventValueChanged]; [self.view addSubview:self.segmentedControl]; // 设置背景图像为透明图像 UIImage *transparentImage = [[UIImage alloc] init]; [self.segmentedControl setBackgroundImage:transparentImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [self.segmentedControl setBackgroundImage:transparentImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; [NSLayoutConstraint activateConstraints:@[ [self.segmentedControl.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], [self.segmentedControl.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], [self.segmentedControl.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:100], [self.segmentedControl.heightAnchor constraintEqualToConstant:40] ]]; } - (void)setUpScrollView { self.scrollView = [[UIScrollView alloc] init]; self.scrollView.pagingEnabled = YES; self.scrollView.translatesAutoresizingMaskIntoConstraints = NO; self.scrollView.showsHorizontalScrollIndicator = NO; self.scrollView.showsVerticalScrollIndicator = NO; self.scrollView.delegate = self; [self.view addSubview:self.scrollView]; [NSLayoutConstraint activateConstraints:@[ [self.scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], [self.scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor], [self.scrollView.topAnchor constraintEqualToAnchor:self.segmentedControl.topAnchor], [self.scrollView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:-75] ]]; } - (void)configureImages { for (int i = 0; i < self.titles.count + 2; i++) { NSString *imageName; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.scrollView.frame.size.width * i, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)]; if (i == 0) { imageName = @"香水1.jpg"; } else if (i == self.titles.count + 1) { imageName = @"女士1.jpg"; } else { imageName = [NSString stringWithFormat:@"%@1.jpg", self.titles[i - 1]]; } UIImage *image = [UIImage imageNamed:imageName]; if (image) { imageView.image = image; } else { NSLog(@"Image not found: %@", imageName); } imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.clipsToBounds = YES; // 确保裁剪内容 [self.scrollView addSubview:imageView]; [self.imageViews addObject:imageView]; } self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * (self.titles.count + 2), self.scrollView.frame.size.height); CGPoint contentOffset = CGPointMake(self.scrollView.frame.size.width, 0); [self.scrollView setContentOffset:contentOffset animated:NO]; } - (void)segmentChanged:(UISegmentedControl *)sender { NSInteger index = sender.selectedSegmentIndex; [self.scrollView setContentOffset:CGPointMake(self.view.frame.size.width * (index + 1), 0) animated:YES]; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { CGFloat offsetX = scrollView.contentOffset.x; CGFloat pageWidth = scrollView.frame.size.width; int index = (int)(offsetX / pageWidth + 0.5) % ((int)self.imageViews.count + 2); if (index == 0) { self.segmentedControl.selectedSegmentIndex = 4; } else if (index == 6) { self.segmentedControl.selectedSegmentIndex = 0; } else { self.segmentedControl.selectedSegmentIndex = index - 1; } } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat offsetX = scrollView.contentOffset.x; CGFloat pageWidth = scrollView.frame.size.width; if (offsetX >= pageWidth * 6) { // 滚动到假的最后一页,瞬间跳到实际第一页 [self.scrollView setContentOffset:CGPointMake(pageWidth, 0) animated:NO]; } else if (offsetX <= 0) { // 滚动到假的第一页,瞬间跳到实际最后一页 [self.scrollView setContentOffset:CGPointMake(pageWidth * 5, 0) animated:NO]; } } @end
scrollView
之中的图片内容是空白的,我们得到的界面是这样的:
其实在 viewDidLoad
,scrollView
是已经布局在了界面之上,但是为什么没有画面呢?是因为在自动布局的过程之中分为几个阶段:
viewDidLoad
阶段:在 viewDidLoad
方法中,我们在其中创建和配置视图的约束,但实际的布局计算和应用尚未发生。viewWillAppear:
阶段:在视图控制器即将显示之前,自动布局系统会进行一次布局计算和应用。在这个阶段,系统会根据视图的约束来计算视图的大小和位置,并应用于屏幕上的实际视图。viewDidLayoutSubviews
阶段:在视图控制器视图的布局发生变化时,例如设备旋转、状态栏变化或者视图控制器自身布局发生变化时,自动布局系统会再次进行布局计算和应用。这个阶段是在视图完成布局后调用的,所以对于scrollView
之中的图片内容,应该是在自动布局计算结束之后,可以在 viewDidLayoutSubviews
方法中进行进一步的布局调整或更新。因此,虽然我们在 viewDidLoad
方法中创建和配置视图的约束,但实际的布局计算和应用发生在稍后的阶段,主要是在 viewWillAppear:
和 viewDidLayoutSubviews
阶段。由于在 viewDidLoad
方法中实际的布局计算和应用尚未发生,所以在 viewDidLoad
方法中尝试设置图片视图的位置或大小,无法得到预期的结果。
那解决方法其实很简单,我们只要将将 configureImages
方法放在 viewDidLayoutSubviews
方法中以确保在正确的时机设置图片视图的尺寸。
而在 viewDidLayoutSubviews
方法中,视图层次结构已经完成布局,并且子视图的大小和位置已经确定。这是因为 viewDidLayoutSubviews
方法在每次视图布局发生变化时都会被调用,包括视图控制器的初始布局以及后续的布局更改,例如设备旋转、状态栏变化或者视图控制器自身布局发生变化。
因此,将 configureImages
方法放在 viewDidLayoutSubviews
方法中,可以确保在正确的时机设置图片视图的尺寸,以适应当前的布局状态。这样,无论是初始布局还是后续的布局更改,都能够正确地显示图片在 UIScrollView
中。
总结起来,将 configureImages
方法放在 viewDidLayoutSubviews
方法中是为了确保在视图布局完成后再设置图片视图的尺寸,以适应当前的布局状态。这样可以解决图片在 UIScrollView
中无法正确显示的问题。
最后结果如上图。
在仿写NARA的过程之中,我发现自带的字体和logo本身的差距较大,于是想着自己找个更美观的艺术字来进行使用,于是学习了如何添加字体。
在网上查找相关的字体下载网站,下载后缀为.ttf 或者为 .otf的文件,与添加图片类似,直接将文件拖拽至项目之中,记得勾选add to target
然后打开info文件,在Imformation property List
的目录下添加 “Fonts provided by application”的文件
最后添加文件的全称(加上后缀),添加到这个文件夹之下
因为可能存在字体本身的名字和我们添加的.ttf的文件上的名字不同,那么我们就要找出所属的字体名字。我们可以用上这个程序:
for(NSString *familyname in [UIFont familyNames]){
NSLog(@"family: %@",familyname);
for(NSString *fontName in [UIFont fontNamesForFamilyName:familyname]){
NSLog(@"----font: %@",fontName);
}
NSLog(@"--------------");
}
这段代码的意思就是,是打印出所有非系统字体的类以及具体的字体名字,这是一个很直接的方法,但由于xcode也有自带的非系统字体,那么如果字体原先的名字和我们使用的.ttf文件的差别很大的话,我们要将他们找出来的话还是很麻烦的,不过一般情况下字体自身的名字是会和我们添加的.ttf文件名字相等的。
找到字体名字之后我们可以使用+ (nullable UIFont *)fontWithName:(NSString *)fontName size:(CGFloat)fontSize;
的方法对字体进行运用
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
titleLabel.text = @"ZARA";
titleLabel.font = [UIFont fontWithName:@"TimesNewRomanPS-BoldItalicMT" size:60];
titleLabel.textAlignment = NSTextAlignmentLeft;
经过以上的操作我们就可以使用自定义的字体啦
应用图标和启动页面又被称作app icon和launch image
对于应用图标的使用其实很简单
我们在左侧菜单栏找到Assets
,点进去后右键在iOS选项之中点击添加New iOS App icon
,然后将自己想要的图片放入即可。(注:要求的图片应该是1024✖️1024 pt)
那么对于启动页面,我们可以在左侧菜单栏的Launch Screen
之中将相应的图片界面给手动添加进去,如下图所示
将以上的内容综合一下,我们就得到了具备应用图标和启动页面,看起来有点像模像样的ZARA啦
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。