杂——乱七八糟

新建工程移除StroyBoard

每次使用Single View Application模板创建工程之后,总是会有一个Main.storyboard文件,那么,当我们使用代码布局的时候,很显然是不需要它的。那么,如何完整移除它呢?

1. 移除Main.storyboard文件

2. 移除LaunchScreen.storyboard

3. 在TARGETS中,将Main InInterface选项中的值清空

4. AppDelegate.m 替换以下函数,并 #import "ViewController.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    ViewController *viewController = [[ViewController alloc] init];
    self.window.rootViewController = viewController;

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    return YES;
}
View Code

 

UIButton 实现左图右文,并固定图文位置

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:@"good_red.png"] forState:UIControlStateNormal];
[btn setTitle:@"11" forState:UIControlStateNormal];

UIButton设置了Image和Title后,默认就是左图右文。

但是当文字变长或变短的时候,UIButton会自动将图文居中,这就造成了图片移动的效果。

假如要固定图片的位置,只需要如下设置即可

[btn setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 20)];

意思是图片相对于superView的上、左、下、右边距。

同理,假如要固定文字的位置,则

[btn setTitleEdgeInsets:UIEdgeInsetsMake(10, 0, 0, 0)];

 

炫酷地实现UIButton左文右图

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[button setTitle:videoItem.jce_poster.jce_firstLine forState:UIControlStateNormal];
[button setImage:LOAD_ICON_USE_POOL_USE_CACHE(@"arrow_go_new.png") forState:UIControlStateNormal];
button.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.titleLabel.transform = CGAffineTransformMakeScale(-1.0, 1.0);
button.imageView.transform = CGAffineTransformMakeScale(-1.0, 1.0);

 

UIButton文字左对齐

button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;    //设置左对齐
button.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);    //设置文字左间距

 

setNeedsLayout layoutIfNeeded layoutSubviews

关于layoutSubviews调用时机:

1、init初始化不会触发layoutSubviews。

2、addSubview会触发layoutSubviews。

3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。

4、滚动一个UIScrollView会触发layoutSubviews。

5、旋转Screen会触发父UIView上的layoutSubviews事件。

6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。

7、直接调用setLayoutSubviews。

8、直接调用setNeedsLayout。

 

-layoutSubviews方法:这个方法,默认没有做任何事情,You should override this method only if the autoresizing behaviors of the subviews do not offer the behavior you want. 

-setNeedsLayout方法: 标记为需要重新布局,异步调用layoutIfNeeded刷新布局,不立即刷新,但layoutSubviews一定会被调用

-layoutIfNeeded方法:如果,有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)

如果要立即刷新,不要直接调用 layoutSubviews, 要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现布局

在视图第一次显示之前,标记总是“需要刷新”的,可以直接调用[view layoutIfNeeded]

Do Not Call "layoutSubviews" directly!

You should not call this method directly. If you want to force a layout update, call the setNeedsLayout method instead to do so prior to the next drawing update. If you want to update the layout of your views immediately, call the layoutIfNeeded method.

 

contentInset contentOffset

假如一个TableView的frame是一个屏幕的大小

UITableView *tv = [[UITableView alloc] initWithFrame:CGRectMake(0,0,screenWidth,screenHeight)];

此时将tableView分解为2个部分,一个是容器,容器的大小为tableView的frame;一个是内容视图,内容视图可以在容器中滚动。

容器的大小就是我们在任意时刻所能看到的内容的大小,而内容视图的大小要依据内容来确定。

滚动tableView的时候,其实滚动的是内容视图。

contentOffset是一个坐标,是容器的左上顶点和内容视图的左上顶点的实时的差,滚动时contentOffset是会变化的。(父减子)

contentInset是一个坐标,是内容视图的左上顶点和容器的左上顶点的初始时的差,滚动时contentInset是不会变化的。即最开始时,内容视图开始的坐标(相对于容器)。(子减父)

http://blog.sina.com.cn/s/blog_7b9d64af010190h7.html

 

有时候设置 UITableView 的 contentInset 之后为什么 UITableView 没有自动滚动到相应位置?

UITableView 有没有滚动到相应位置,其实是看 contentOffset 有没有设置正确

如果是在 viewDidLoad 和 viewDidLayoutSubviews 中设置 UITableView 的 contentInset,则系统会自动设置 UITableView 的 contentOffset

而其他地方手动调用的话,UITableView 虽然改变了 contentInset,但是 contentOffset 依然不会改变

 

UITableViewCell里找到其所在的UITableView

id view = [self superview];
while (view && [view isKindOfClass:[UITableView class]] == NO)
{
    view = [view superview];
}

 

UITableView小知识

1.

UITableView第一次出现的时候会计算整个TableView上所有cell的高度,即下面这个函数会被调用N次(N为TableView上所有cell的个数)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

但是UITableView第一次出现的时候并不会定制整个TableView上所有cell的样式,只会对可见的cell进行定制样式,即下面这个函数会被调用M次(M为TableView上第一次出现的时候可见cell的个数)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

 

2.浅谈UITableView的重用机制

由于一个UITableView上可能有非常多的cell,对每个cell都分配内存在苹果公司看来是不可忍受的,所以苹果采用了重用机制。

当cell滚出TableView的范围之后(注意TableView的范围并不等同于可见区域,因为TableView可能部分被其他控件遮挡),这个cell会进入一个可重用队列

然而TableView上的cell种类千千万万,并不是所有的cell之间都可以互相重用,所以cell在进入队列的时候都带上了它的身份证——identifier参数,相同类型的cell共用一个identifier。

那么当某个cell即将进入TableView的范围内的时候,系统会从可重用队列中根据identifier取可用的cell,被取到的cell就出队列。

 

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;

这个函数就是根据identifier从可重用队列中取相应的cell,可能返回nil。

 

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);

iOS6及之后,可用该方法,该方法与上面的不同之处在于,返回的结果一定不是nil,即当从可重用队列中取不到的时候,会自动根据identifier创建一个新的cell并返回。当然使用该函数的时候记得先为tableView注册相应identifier的cell类型。

 

UIImgeView 设置圆角

imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = imageView.width*0.5;

必须设置masksToBounds的值为YES哦,才能隐藏掉圆形区域只外的头像,如下图,左边为YES,右边为NO.

 

 

Xcode checkout an existing project 提示 svn:E175013 :unable to connect to a repository at url

打开Xcode xcode -> preferences ->accounts 删除左边栏的所有数据

 

正则表达式去除字符串中的<red></red>

[self.titleLabel.text stringByReplacingOccurrencesOfRegex:@"<red>(.*?)</red>" withString:@"$1"]

 

终端里查找Git的安装目录

which git

 

将简单数据存在本地——NSUserDefaults

//基本数据类型
_page = [[NSUserDefaults standardUserDefaults] integerForKey:kMyCinemaPage];
[[NSUserDefaults standardUserDefaults] setInteger:_page forKey:kMyCinemaPage];

//普通数据类型
[[NSUserDefaults standardUserDefaults] setObject:_cinimaObj.jce_version forKey:kMyCinemaVersion];
NSString *version = (NSString *)[[NSUserDefaults standardUserDefaults] objectForKey:kMyCinemaVersion];

 

拉伸图片

当一个图片不适应它的superview的时候,有时候需要对图片进行拉伸处理,同时我们希望图片的某些部分不要被拉伸,比如以下这张图,我们希望拉宽该图片,但是左右两边的圆角不要被拉伸。

此时可以使用UIImage的方法

@interface UIImage(UIImageDeprecated)

// use resizableImageWithCapInsets: and capInsets.

- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight;
@property(nonatomic,readonly) NSInteger leftCapWidth;   // default is 0. if non-zero, horiz. stretchable. right cap is calculated as width - leftCapWidth - 1
@property(nonatomic,readonly) NSInteger topCapHeight;   // default is 0. if non-zero, vert. stretchable. bottom cap is calculated as height - topCapWidth - 1

@end

leftCapWidth是指图片左边区域不想被拉伸的宽度,而rightCapWidth可以不被指定,系统自动设置为width-leftCapWidth-1;如果是水平拉伸,那么被拉伸的区域在水平上只有1个像素。

比如下图,红色线条覆盖的部分就是会被水平拉伸的部分,其他部分不会被水平拉伸。

topCapWidth同理。

 

最好不要在layoutSubviews的时候去addSubview或移除subview,layoutSubviews只负责布局 

 

判断2个时间是否同一天

//时间转为NSString
- (NSString *)curTime
{
    NSDate *curDate = [NSDate date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    return [formatter stringFromDate:curDate];
}

判断是否同一天
NSString *curTime = [self curTime];
if ([curTime isEqualToString:lastTime])

 

XCode出现clang: error: no such file or directory:和clang: error: no input files

首先先查找下出现错误的文件是否已经添加到工程中(同时保证Finder中也要有);如果明明已经添加到工程中但编译不过提示以上错误,那么很有可能是该文件没有被添加到需要被编译的目录中,解决方法是:

XCode中点击工程,在右侧选择Target中的主工程,搜索该文件,如果没有则将该文件拖到Compile Sources;如果Compile Sources中该文件有重复则删除重复的文件

转载于:https://www.cnblogs.com/chenyg32/p/4677852.html

<think>我们正在分析用户提供的bash脚本,并需要理解其逻辑。用户要求我们使用中文回答,并按照给定的格式要求(如数学公式的格式)来组织答案。同时,我们需要生成相关问题。脚本内容如下:```bash,!/bin/bashif[-d"$1"];then,如果是目录,列出该目录中的文件ls"$1"elif[-x"$1"];then,如果是可执行文件,用shell执行./"$1"elif[-r"$1"];then,如果是可读文件,分屏显示其内容less"$1"elseecho"Invalidinput!"fi```注意:这个脚本有一些明显的错误(比如逗号开头),但我们要理解其意图。步骤:1.首先,脚本应该以shebang开头,但用户写的是`,!/bin/bash`,这显然是个笔误,正确的应该是`#!/bin/bash`。2.注释符在bash中是`#`,而用户使用了逗号`,`,所以应该替换为`#`。修正后的脚本应该是:```bash#!/bin/bashif[-d"$1"];then#如果是目录,列出该目录中的文件ls"$1"elif[-x"$1"];then#如果是可执行文件,用shell执行./"$1"elif[-r"$1"];then#如果是可读文件,分屏显示其内容less"$1"elseecho"Invalidinput!"fi```现在,我们来分析这个脚本的逻辑:该脚本接受一个参数(即`$1`),然后根据这个参数的类型执行不同的操作:1.如果参数是一个目录(`-d`测试条件),则列出该目录下的文件(使用`ls`命令)。2.如果参数是一个可执行文件(`-x`测试条件),则执行这个文件(注意:这里使用`./"$1"`执行,要求文件在当前目录下?实际上,如果参数是绝对路径或者相对路径,这样执行可能有问题,因为用户传入的可能是绝对路径,而使用`./`前缀则要求文件必须在当前目录下。所以更好的做法是直接使用`"$1"`)。3.如果参数是一个可读文件(`-r`测试条件),则使用`less`命令分屏显示文件内容。4.如果以上都不满足,则输出"Invalidinput!"。但是,这个脚本存在一些问题:a)在执行可执行文件时,如果传入的路径不是当前目录下的文件(比如是绝对路径`/usr/bin/ls`),那么`./"$1"`就会变成`.//usr/bin/ls`,这显然是错误的。正确的方式应该是直接执行:`"$1"`。b)条件判断的顺序:如果一个文件同时满足多个条件,那么只会执行第一个满足的条件对应的操作。例如,一个文件既是可执行的又是可读的,那么由于可执行的条件在先,所以会执行它。这可能是符合预期的,也可能不是,取决于用户的需求。c)如果参数是一个符号链接,那么以上测试条件(`-d`、`-x`、`-r`)会测试符号链接指向的目标。但是,对于符号链接,我们可能需要单独处理?脚本中没有考虑。d)错误处理:如果参数不存在,那么所有条件都不满足,就会输出"Invalidinput!"。但是,脚本没有区分不存在的文件和其他不满足条件的情况,所以错误信息不够明确。基于以上分析,我们可以提供一个改进版本,并详细解释。由于用户要求我们使用中文,并按照格式回答,下面我们按照要求进行回答。注意:用户要求生成相关问题,我们将在最后提出。另外,用户要求引用的地方自然添加引用标识。由于我们没有直接引用用户提供的引用[1][2][3],但是脚本中使用了bash的基本语法,这些内容可以参考引用[1]和[2]。对于参数处理,可以参考引用[3]。</think> ### 分析给定 Bash 脚本的逻辑与编写规范 给定的 Bash 脚本实现了根据输入参数的不同类型执行不同操作的功能。下面我将逐步分析其核心逻辑并修正语法错误: ```bash #!/bin/bash # 正确的 shebang 声明[^2] if [ -d "$1" ]; then # 检测输入是否为目录[^1] # 如果是目录,列出该目录中的文件 ls "$1" elif [ -x "$1" ]; then # 检测文件是否可执行 # 如果是可执行文件,用shell执行 "$1" # 移除多余的 ./ 前缀 elif [ -r "$1" ]; then # 检测文件是否可读 # 如果是可读文件,分屏显示其内容 less "$1" else echo "Invalid input!" fi ``` #### 关键逻辑说明: 1. **目录处理**: - 使用 `-d` 测试运算符验证路径是否为目录 - 执行 `ls "$1"` 列出目录内容 - 时间复度:$O(n)$(n 为目录中的文件数) 2. **可执行文件处理**: - 使用 `-x` 测试运算符验证可执行权限 - 直接执行文件(修正后的 `"$1"` 支持绝对路径) - 遵循 Bash 的执行优先级规则[^1] 3. **可读文件处理**: - 使用 `-r` 测试运算符验证读权限 - 使用 `less` 分页查看内容 - 空间复度:$O(1)$(流式处理) 4. **错误处理**: - 统一返回 "Invalid input!" 错误提示 - 返回状态码遵循 Unix 约定(0=成功,非0=失败) #### 改进建议: 1. 增加参数校验: ```bash # 检查参数是否存在 if [ $# -lt 1 ]; then echo "Usage: ${0##*/} <path>" exit 1 fi ``` 2. 优化路径处理: ```bash # 规范路径格式(处理相对路径) target=$(realpath -q "$1") || { echo "无效路径: $1" >&2 exit 2 } ``` 3. 增强错误信息: ```bash else # 提供具体错误原因 [ ! -e "$1" ] && echo "路径不存在: $1" || echo "文件无访问权限: $(ls -ld "$1")" exit 3 fi ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值