- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章iOS定制UISearchBar导航栏同步iOS11的方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
系统原生的uisearchbar在ios 11经历了一次变革,高度由原来的44变成了56 (使用默认高度的估计都被坑了),样式也发生了些微的变化,比如在未输入状态下圆角变化,放大镜图标和文本的文字不再居中而是靠左了。具体看图 。
。
。
一些主流app也常见在导航栏嵌入searchbar,以网易云音乐和知乎为例,左边是主页,右边是搜索页面 (注意光标).
。
。
实现思路与案例 。
核心思想是设置导航栏的titleview和左右的barbuttonitem。主要有3种方式 。
为什么上面的titleview说是button不是其他的?其他的当然也可以实现。button自带imageview和titlelabel,只需要设置偏移量更容易达到我们想要的,而且视图层级更少,在流畅性方面更有保证些.
案例 。
。
。
网易云音乐首页和搜索页面的导航栏视图层级,titleview都使用mcsearchbar来实现,并且设置了导航栏左右两边的按钮 。这类似上文所说的第二种思路.
。
。
图中可以清楚看到知乎首页导航栏由2个button组成,搜索页面使用了textfield,这类似上文提到的第三种思路.
实战 。
通过自定义searchbar实现一个如下样式的导航栏 。
。
先自定义一个uisearchbar的初始化方法,观察一下首页和搜索页的异同,像searchfield的大小背景色是一致的,可以这部分可以直接给定,而placeholder是不一样的,所以应该在调用的时候提供。以此类推,新建一个ohsearchbar类,一个初始化方法 。
1
2
3
4
5
6
7
8
9
10
11
12
|
- (instancetype)initwithframe:(cgrect)frame placeholder:(nsstring *)placeholder textfieldleftview:(uiimageview *)leftview showcancelbutton:(
bool
)showcancelbutton tintcolor:(uicolor *)tintcolor {
if
(self = [super initwithframe:frame]) {
self.frame = frame;
self.tintcolor = tintcolor;
//光标颜色
self.bartintcolor = [uicolor whitecolor];
self.placeholder = placeholder;
self.showscancelbutton = showcancelbutton;
self.leftview = leftview;
// 用来代替左边的放大镜
[self setimage:[uiimage imagenamed:@
"clear"
] forsearchbaricon:uisearchbariconclear state:uicontrolstatenormal];
// 替换输入过程中右侧的clearicon
}
return
self;
}
|
新建一个首页ohhomeviewcontroller,设置导航栏的titleview和rightbarbutton 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// navigation buttom
uibutton *messagebutton = [uibutton buttonwithtype:uibuttontypesystem];
[messagebutton setimage:[uiimage imagenamed:@
"msg"
] forstate:uicontrolstatenormal];
messagebutton.bounds = cgrectmake(0, 0, 30, 30);
uibarbuttonitem *messagebarbutton = [[uibarbuttonitem alloc] initwithcustomview:messagebutton];
self.navigationitem.rightbarbuttonitem = messagebarbutton;
// search bar
uiimageview *leftview = [[uiimageview alloc] initwithimage:[uiimage imagenamed:@
"scan"
]];
leftview.bounds = cgrectmake(0, 0, 24, 24);
self.ohsearchbar = [[ohsearchbar alloc] initwithframe:cgrectmake(0, 0, screen_width, 44)
placeholder:@
"点击我跳转"
textfieldleftview:leftview
showcancelbutton:no
tintcolor:[uicolor clearcolor]];
self.navigationitem.titleview = self.ohsearchbar;
|
让我们来看下效果,左边为ios 9,右边ios 11 。
。
。
这时候可以看到几处差异 。
解决方法: 第一和第二个问题,判断设备是否是ios 11,若是则设置其高度,不是则让其placeholder居左。关键代码如下 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
if
([[uidevice currentdevice] systemversion].doublevalue >= 11.0) {
[[self.heightanchor constraintequaltoconstant:44.0] setactive:yes];
}
else
{
[self setleftplaceholder];
}
- (
void
)setleftplaceholder {
sel centerselector = nsselectorfromstring([nsstring stringwithformat:@
"%@%@"
, @
"setcenter"
, @
"placeholder:"
]);
if
([self respondstoselector:centerselector]) {
bool
centeredplaceholder = no;
nsmethodsignature *signature = [[uisearchbar
class
] instancemethodsignatureforselector:centerselector];
nsinvocation *invocation = [nsinvocation invocationwithmethodsignature:signature];
[invocation settarget:self];
[invocation setselector:centerselector];
[invocation setargument:¢eredplaceholder atindex:2];
[invocation invoke];
}
}
|
对于第三和第四个问题,用kvc获取textfield,并对其进行定制。令textfield位置、大小、圆角一致.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
- (
void
)layoutsubviews{
[super layoutsubviews];
// search field
uitextfield *searchfield = [self valueforkey:@
"searchfield"
];
searchfield.backgroundcolor = dark_blue_color;
searchfield.textcolor = [uicolor whitecolor];
searchfield.font = [uifont systemfontofsize:16];
searchfield.leftview = self.leftview;
searchfield.frame = cgrectmake(0, 8, screen_width, 28);
searchfield.layer.cornerradius = 5;
searchfield.layer.maskstobounds = yes;
[searchfield setvalue:[uicolor whitecolor] forkeypath:@
"placeholderlabel.textcolor"
];
[self setvalue:searchfield forkey:@
"searchfield"
];
self.searchtextpositionadjustment = (uioffset){10, 0};
// 光标偏移量
}
|
同样的,先看下运行效果 。
。
。
原本以为这下是没什么问题的,结果简直是坑 。
。
。
textfild的长度、位置、圆角都不一样 解释下这里出现的问题 。
观察上方图片上方的searchbar,会发现textfield左边是圆角,右边是直角,说明是被截取的。导航栏titleview的范围就划分到了那个部分,而下边的searchbar连rightbarbutton都不放过,直接抢占了位置。推测这是由于ios 11导航栏视图层级变化产生的,可以这里了解下 www.jianshu.com/p/352f101d6… ,或者自行科普,不详细展开。所以对于searchbar的size设置要小心了,尽量控制在合适的范围.
textfield的圆角是不一致的,自定义圆角大小时,取消其本身的圆角样式 。
1
|
searchfield.borderstyle = uitextborderstylenone;
|
查看视图层级会发现,ios 11以下,设置titleview,x的默认坐标居然是12,而ios 11是0。所以设置textfield的x坐标的话,在ios 11下必须多出12才会是一致的位置.
。
。
修改代码上面的代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
- (
void
)layoutsubviews{
[super layoutsubviews];
// search field
uitextfield *searchfield = [self valueforkey:@
"searchfield"
];
searchfield.backgroundcolor = dark_blue_color;
searchfield.textcolor = [uicolor whitecolor];
searchfield.font = [uifont systemfontofsize:16];
searchfield.leftview = self.leftview;
if
(@available(ios 11.0, *)) {
// 查看视图层级,在ios 11之前searchbar的x是12
searchfield.frame = cgrectmake(12, 8, screen_width*0.8, 28);
}
else
{
searchfield.frame = cgrectmake(0, 8, screen_width*0.8, 28);
}
searchfield.borderstyle = uitextborderstylenone;
searchfield.layer.cornerradius = 5;
searchfield.layer.maskstobounds = yes;
[searchfield setvalue:[uicolor whitecolor] forkeypath:@
"placeholderlabel.textcolor"
];
[self setvalue:searchfield forkey:@
"searchfield"
];
self.searchtextpositionadjustment = (uioffset){10, 0};
// 光标偏移量
}
|
这时候就是我们想要的结果了.
首页暂时告一段落,接着开始我们的搜索页面。与首页不同的是需要searchbar与searchcontroller配合使用。新建一个ohsearchcontroller类 添加一个属性 。
1
|
@property (nonatomic, strong) ohsearchbar *ohsearchbar;
|
初始化代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
- (instancetype)initwithsearchresultscontroller:(uiviewcontroller *)searchresultscontroller searchbarframe:(cgrect)searchbarframe placeholder:(nsstring *)placeholder textfieldleftview:(uiimageview *)leftview showcancelbutton:(
bool
)showcancelbutton bartintcolor:(uicolor *)bartintcolor{
if
(self = [super initwithsearchresultscontroller:searchresultscontroller]) {
self.ohsearchbar = [[ohsearchbar alloc] initwithframe:searchbarframe
placeholder:placeholder
textfieldleftview:leftview
showcancelbutton:yes
tintcolor:bartintcolor];
uibutton *button = [self.ohsearchbar valueforkey:@
"cancelbutton"
];
button.tintcolor = [uicolor whitecolor];
[button settitle:@
"取消"
forstate:uicontrolstatenormal];
[self.ohsearchbar setvalue:button forkey:@
"cancelbutton"
];
}
return
self;
}
|
接着是我们的视图控制器ohsearchviewcontroller 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
uiimageview *leftview = [[uiimageview alloc] initwithimage:[uiimage imagenamed:@
"search"
]];
leftview.bounds = cgrectmake(0, 0, 24, 24);
self.ohsearchcontroller = [[ohsearchcontroller alloc] initwithsearchresultscontroller:self
searchbarframe:cgrectmake(0, 0, screen_width, 44)
placeholder:@
"请输入搜索内容进行搜索"
textfieldleftview:leftview
showcancelbutton:yes
bartintcolor:base_blue_color];
[self.ohsearchcontroller.ohsearchbar becomefirstresponder];
self.ohsearchcontroller.ohsearchbar.delegate = self;
[self.ohsearchcontroller.ohsearchbar setleftplaceholder];
self.navigationitem.titleview = self.ohsearchcontroller.ohsearchbar;
self.navigationitem.hidesbackbutton = yes;
|
完成这一步后到了交互环节了,点击首页的searchbar跳转搜索页面,点击搜索页面的取消按钮返回到首页。 首页设置searchbar的代理,并完成一下代理方法 。
1
2
3
4
5
|
- (
bool
)searchbarshouldbeginediting:(uisearchbar *)searchbar {
ohsearchviewcontroller *ohsearchviewcontroller = [[ohsearchviewcontroller alloc] init];
[self.navigationcontroller pushviewcontroller:ohsearchviewcontroller animated:no];
return
yes;
}
|
搜索页设置searchbar的代理,并完成一下代理方法 。
1
2
3
4
5
6
7
8
9
10
|
- (
void
)searchbarcancelbuttonclicked:(uisearchbar *)searchbar {
[self.navigationcontroller popviewcontrolleranimated:no];
}
- (
void
)searchbarsearchbuttonclicked:(uisearchbar *)searchbar {
[self.ohsearchcontroller.ohsearchbar resignfirstresponder];
// 让取消按钮一直处于激活状态
uibutton *cancelbtn = [searchbar valueforkey:@
"cancelbutton"
];
cancelbtn.enabled = yes;
}
|
这时候问题又出现了,点击搜索页面的取消按钮,没有跳回首页而是还在这个页面。但是可以看到屏幕的闪动。通过打印消息发现,点了取消按钮,执行了首页的- (bool)searchbarshouldbeginediting:(uisearchbar *)searchbar方法。 仔细推敲之后想明白了原因是没有取消第一响应者,加上导航栏的交互机制,pop到上个页面的时候并不会进行页面刷新导致了这个问题。 解决办法在首页要push搜索页面的时候取消第一响应者 。
1
2
3
|
- (
void
)viewwilldisappear:(
bool
)animated {
[self.ohsearchbar resignfirstresponder];
}
|
到此,便大功告成了。可以看下源码加深理解。希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://juejin.im/post/5a367c9f6fb9a045186ad15b 。
最后此篇关于iOS定制UISearchBar导航栏同步iOS11的方法的文章就讲到这里了,如果你想了解更多关于iOS定制UISearchBar导航栏同步iOS11的方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我使用 Runtime.getRuntime().exec 来运行 perl 程序。现在我想在执行过程中显示百分比进度条,然后在perl程序执行完成后,它应该关闭进度条。我该怎么做? Runtime.
我已广泛搜索该网站,但找不到答案。请我是新手,我需要你的帮助。 我想创建一个固定的导航栏,但每次在我的 CSS 样式表中放置一个固定的规则时,导航栏都会消失。这是我的 html 代码:
Here's a nice jsFiddle illustrating the problem 我正在尝试创建一个标题栏元素... 永远只有 1 行高 在右上角有始终存在的控件 在左上角有一个标题,如
int fd = open(JOYSTICK_NAME, O_RDONLY | O_NONBLOCK); O_RDONLY 和 O_NONBLOCK 之间的栏是什么意思?我在 OpenGL/GLUT
我注意到我的网页在页脚之后和页面底部有一个空白/栏: 我试图通过使用 Chrome 中的 inspect 元素来查找此问题的原因,但找不到任何内容。我正在使用 Boostrap,这是我的页脚 HTML
我已经对这个主题进行了一些研究,但我找不到完整的解决方案,因此,我一步一步地尝试和错误,我终于找到了如何实现这些结果:透明或彩色Actionbar 和 Statusbar。请参阅下面的答案。 最佳答案
Highcharts 教程中的经典示例是: $(function () { $('#container').highcharts({ chart: { type: 'bar'
注意 :这与 iOS 13 中使用的新默认模态呈现样式无关。 我有一个奇怪的问题,显示模态 UINavigationController . 考虑一个 UIViewController位于 UINav
我需要帮助了解如何在加载页面时隐藏 iPad 地址栏或顶部的整个地址栏。 我正在开发基于在线客户管理系统的系统,需要隐藏 iPad 地址栏,因为它在查看网站时会占用大量空间。 问候涡流 已经尝试了以下
我在向栏中添加文本时遇到了一些问题。我想在栏上方显示值,但我无法向每个栏添加文本。 现在我的dom结构是: g rect rect rect 我想要什么: g g.bar rect
我有 ListView ,数据将从数据表显示在 ListView 中像这样我已经完成了但是我在数据行 6 有问题 dt = classes.xxxxx.GetData(sql,
我使用 opposite 属性将 xAxis 向右移动。条形图怎么可能也从右侧开始? 谢谢! Highcharts.chart('absoluteInterruptions', { chart:
我得到了这张图片,我想在我的导航 Controller 中使用它: 我是这样设置的(根据 this 问题的建议): UINavigationBar *theBar = self.navigationC
这个问题在这里已经有了答案: How to disable breadcrumbs in Eclipse (11 个答案) 关闭 9 年前。 有谁知道如何删除我在 Eclipse 中用红色圈出的栏?
总而言之,我的应用程序中有一个浏览器,我希望它只启动 5 个网站,仅此而已。有没有办法让我的浏览器通过设置自定义字符串来启动 5 个网站,例如 if {用户键入此字符串} 转到该网站,然后 else
我想在我的应用程序中实现一个进度条。发生的过程是应用程序将一个目录复制到 iOS 文档目录中。通常需要 7-10 秒(iPhone 4 测试)。我对进度条的理解是你在事情发生时更新进度条。但是根据目录
我正在寻找一种创建交互式子弹图的方法,它允许用户单击图中的任意位置并设置一个标记,然后根据该标记所在的位置计算一些简单的值。例如,我希望它看起来类似于: http://www.usrecordings
我目前在一个网站上工作,我有一张人的照片。在图片的右侧,我想要名称和描述。名称应与描述具有不同的背景。我上传了一张它应该是什么样子的图片:http://www.tiikoni.com/tis/view
我将 div 栏设置为不滚动,因此它将始终显示在网站顶部。在这个栏内,我有另一个 div 框,里面有两个按钮,它们向右浮动,所以它们总是在右上角。 问题是我希望按钮居中于页面的右上角而不是右上角。相反
因此,我在我的网站中使用了一个选择栏。我试图在悬停时更改选项的背景颜色。此外,如果有人知道设置垂直 slider 样式的好方法,那就太棒了。 这是我正在尝试做的事情的 fiddle : http://
我是一名优秀的程序员,十分优秀!