学习HM微博项目第8天
步骤:发微博01-导航栏内容 -> 发微博02-自定义TextView -> 发微博03-完善TextView和发送微博按钮 -> 发微博04-显示工具条 -> 发微博05-封装工具条和相册 -> 发微博06-发送微博
发微博01-导航栏内容
APP的演示操作:
从APP的演示操作中可知,当点击tabBar的“+”按钮时APP会以modal的方式跳转到发微博的控制器。实现代码如下:
在HMComposeViewController类的viewDidLoad方法中,设置导航栏内容,并添加输入控件(用于输入微博正文),如下:
HMComposeViewController类的初始化方法如下:
发微博02-自定义TextView
APP的演示操作:
前文中,已经初步添加了输入控件UITextView,但是输入控件UITextView并不能完全满足我们的要求,即无法实现占位文字。
所以,新建了一个继承自UITextView的HMTextView类,将占位文字的实现以及输入控件的具体逻辑都封装到HMTextView类中,只将占位文字和占位文字颜色两个属性提供给外界(HMComposeViewController类)使用。如下:
在HMTextView类中,占位文字的实现有多种方式:第一种是添加UILabel,第二种是重写drawRect:方法。在这里,我们采用的是第二种方式。重写drawRect:方法,如下:
观察APP的演示操作,一开始进入发微博界面时,输入控件上显示的是“分享新鲜事”,当我们输入文字后,“分享新鲜事”就会“消失”。这里的实现原理是通知。具体代码如下:
注意:这里不适合使用代理,用通知即可。发出通知后,会触发textDidChange事件,然后重新调用drawRect方法进行重绘。
发微博03-完善TextView和发送微博按钮
APP的演示操作:
在前文的基础上继续完善输入控件,并且当有输入文字后,导航栏的右边发送按钮可以响应(发送微博)。
参考前面,HMComposerViewController监听输入文字同样是采用通知的方式。如下:
其中,textDidChange方法的具体代码如下:
在HMComposerViewController中,监听方法send是用于发送微博,具体代码如下:
说明:
1.完善前文中设置导航栏内容的代码,要考虑是否有微博名,如下:
2.HMTextView类声明了两个属性placedholder和placedholderColor,由于这两个属性不是系统属性,所以在优先级上会较低,我们有时候需要重写它们的setter方法,如下:
3.每一次使用通知,都要注意调用dealloc方法,移除观察者。如下:
发微博04-显示工具条
APP的演示操作:
仔细观察APP的演示操作,工具条一开始是显示在屏幕底部,当键盘弹出时工具条才移动到键盘的顶部。
在HMComposeViewController的viewDidLoad方法添加工具条,如下:
其中,setupToolBar方法如下:
问题:对于工具条的类HMComposerToolbar暂时不要考虑,先弄明白为什么当键盘一出现工具条就会移动键盘的顶部?实现原理是什么?
思路:
1.键盘会在进入发微博页面后就弹出是因为调用了viewDidAppear:方法,如下:
2.弹出键盘后移动工具条,这是因为当键盘的frame发生改变时就会发出通知UIKeyboardWillChangeFrameNotification,触发keyboardWillChangeFrame:事件, 执行动画移动工具条,如下:
其中,keyboardWillChangeFrame:方法,如下:
在HMComposerToolbar类(继承自UIView)中,设置工具条上的按钮。具体代码如下:
@implementation HMComposeToolbar- (id)initWithFrame:(CGRect)frame
{self = [super initWithFrame:frame];if (self) {self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"compose_toolbar_background"]];//初始化按钮[self setupBtn:@"compose_camerabutton_background" highImage:@"compose_camerabutton_background_highlighted"];[self setupBtn:@"compose_toolbar_picture" highImage:@"compose_toolbar_picture_highlighted"];[self setupBtn:@"compose_mentionbutton_background" highImage:@"compose_mentionbutton_background_highlighted"];[self setupBtn:@"compose_trendbutton_background" highImage:@"compose_trendbutton_background_highlighted"];[self setupBtn:@"compose_emoticonbutton_background" highImage:@"compose_emoticonbutton_background_highlighted"];}return self;
}/*** 创建一个按钮*/
- (void)setupBtn:(NSString *)image highImage:(NSString *)highImage
{UIButton *btn = [[UIButton alloc] init];[btn setImage:[UIImage imageNamed:image] forState:UIControlStateNormal];[btn setImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];[self addSubview:btn];}/*** 设置按钮的尺寸*/
- (void)layoutSubviews
{[super layoutSubviews];//设置按钮的frameNSUInteger btnCount = self.subviews.count;CGFloat btnW = self.size.width / 5;CGFloat btnH = self.size.height;for (int i = 0; i< btnCount; i++) {UIButton *btn = self.subviews[i];btn.x = i * btnW;btn.y = 0;btn.width = btnW;btn.height = btnH;}
}
@end
发微博05-封装工具条和相册
APP的演示操作:
仔细观察APP的演示操作,在输入文字下面添加了相册,用于显示发微博的图片。而工具条上的按钮也可以响应某些事件。其实现过程相当复杂。
在HMComposeViewController的viewDidLoad方法添加相册,如下:
其中,setupPhotosView方法如下:
在HMComposePhotosView(继承自UIView)中,添加图片到发微博的相册中,设置图片的frame。关键代码如下:
其中,要将方法addPhoto提供外界,用于从外界添加图片。
在HMComposeToolbar类,完善之前的代码,使得工具条上的按钮可以响应。不同于之前所用到的通知,这里要通过代理来实现按钮的点击事件。
过程:
1.声明代理协议和代理属性,具体代码如下:
2.通知代理对象,具体代码如下:
说明:由于使用到btn.tag,所以要对之前的代码进行完善,如下:
在HMComposeViewController中,遵守HMComposeToolbarDeleagate代理协议,实现代理方法,如下:
其中,openCamera和openAlbum方法分别对应工具条上的“拍照”和“相册”按钮。具体代码如下:
openImagePickerController:设置代理,遵守
UINavigationControllerDelegate和UIImagePickerControllerDelegate代理协议,实现代理方法imagePickerController:didFinishPickingMediaWithInfo:方法,如下:
在imagePickerController:didFinishPickingMediaWithInfo:方法中,取出系统相册里的图片后,调用HMComposePhotosView类的addPhoto方法,将图片添加到发微博的相册photosView中。
发微博06-发送微博
APP的演示操作:
仔细观察APP的演示操作,此时发微博除了发送文字,还可以发送图片。截图如下:
实际上,在前文的send方法中的api接口是没办法发送图片的,需要另外一个接口。这就需要我们考虑两种情况(有图片和没图片)。
完善send方法,具体代码如下:
其中,sendWithImage方法如下:
sendWithoutImage方法如下:
说明:
1.发送带有图片的微博,需要将图片上传到新浪的服务器。
这就涉及HMComposePhotosView类,需要HMComposePhotosView类提供photos属性给外界用来获取图片资源。
由于外界没必要对图片资源进行修改,只需要获取即可。所以对photos属性进行特殊声明(readonly)。如下:
并且要完善下addPhoto方法的代码,如下:
总结:主要掌握好工具条的设置和如何移动,并且进一步加深对readonly属性的认识。
相关文章:

学习HM微博项目第8天
步骤:发微博01-导航栏内容 -> 发微博02-自定义TextView -> 发微博03-完善TextView和发送微博按钮 -> 发微博04-显示工具条 -> 发微博05-封装工具条和相册 -> 发微博06-发送微博 发微博01-导航栏内容 APP的演示操作: 从APP的演示操作中可…...

十五、存储过程与函数
一、存储过程概述 1、简介 含义:存储过程的英文是 Stored Procedure 。它的思想很简单,就是一组经过 预先编译 的 SQL 语句的封装 执行过程:存储过程预先存储在 MySQL 服务器上,需要执行的时候,客户端只需要向服务器…...

php实现助记词转TRX,ETH 私钥和钱包地址
TRX助记词转地址网上都是Java,js或其他语言开发的示例,一个简单的功能需要依赖其他环境来实现表示不能忍,毕竟php是世界上最好的语言。【狗头】 一、知识准备 要实现助记词转TRX私钥和地址,先需要知道助记词和私钥钱包地址之间的…...

浅析可观测系统中sdk的不同引入方式的利与弊
文章前提是不考虑sw的方式引入,同时不考虑在nginx等自动注入js脚本的方式,那么基本就是两种大的形式:cdn引入和本地引入其中cdn引入有两种:cdn同步cdn异步本地引入有两种:npm本地js文件参考知识提前先补充一张图片正文…...
Google Earth导入经纬高(txt文件)
目录 一、提取GNSS数据生成txt文本文件 二、Google Earth导入txt文件 1、启动Google Earth 2、打开vig_result.txt...

Unity客户端开发工程师的进阶之路
UWA技能成长系统是UWA根据学员的职业发展目标,提供技能学习的推荐路径,再将所需学习内容按难易等多维度,设计分成多个学习阶段,可以循序渐进地进行学习。 进入技能成长体系,目标选择高级客户端开发工程师(U…...
2023年全国最新高校辅导员精选真题及答案34
百分百题库提供高校辅导员考试试题、辅导员考试预测题、高校辅导员考试真题、辅导员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 72.心理发展的特点是()。 A.方向性与不可逆性 B.连续性与阶段性…...
chatGPT身份指令
充当 Linux 终端 我想让你充当 Linux 终端。我将输入命令,您将回复终端应显示的内容。我希望您只在一个唯一的代码块内回复终端输出,而不是其他任何内容。不要写解释。除非我指示您这样做,否则不要键入命令。当我需要用英语告诉你一些事情时&…...

基于springboot实现私人健身与教练预约管理系统【源码+论文】分享
基于springboot实现私人健身与教练预约管理系统演示开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea M…...
网络技术领域术语大全,含中英文及缩写,强烈建议收藏!
你好,这里是网络技术联盟站。 今天给大家分享的是网络技术领域相关的术语大全,在文末,我已经将本文整理成一个pdf文档了,大家可以下载到本地以便查阅。 自主访问控(DAC:Discretionary Access Control) 自主访问控制(DAC)是一个…...

C++源码剖析——vector和array
前言:之前看过侯老师的《STL源码剖析》但是那已经是多年以前的,现在工作中有时候查问题和崩溃都需要了解实际工作中使用到的STL的实现。因此计划把STL的源码再过一遍。 摘要:本文描述了llvm中libcxx的std::vector的实现。 关键字&…...

学习linux编程(一)
本文导航一. Linux基础知识杂记0. terminal操作快捷键等1. 为什么vfork的子进程里用return,整个程序会挂掉,而且exit不会(zz)2. 进程内存管理详解3. 关于堆和自由存储区概念的区别4. cache和buffer的区别5. C实现线程池6. 静态函数和虚函数的区别7. C里是…...
pt-query-digest_详细使用方法
pt-query-digest_详细使用方法1. pt介绍1.1. 说明1.2. 安装2 语法选项2.1 所有参数2.2 常见参数2.3 事件和属性2.4 分组2.5 过滤2.6 排序2.7 输出选项2.8 DSN(数据源)选项3. 慢日志3.1 事件属性3.2 分析报告3.2.1 第一部分:总体概况说明3.2.2 第二部分:查…...
基于MATLAB编程的萤火虫FA优化BP神经网络的回归分析
目录 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络激活函数及公式 SVM应用实例,基于fa-svm分类预测 代码 结果分析 展望 BP神经网络的原理 BP神经网络的定义 人工神经网络无需事先确定输入输出之间映射关系的数学方程,仅通过…...
leetcode 消失的数字(面试题)
题目 数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗? 注意:本题相对书上原题稍作改动 示例 1: 输入:[3,0,1] 输出:2 示例 2: 输入&…...

Spring入门篇6 --- AOP
目录1.核心概念AOP(Aspect Oriented Programming)面向切面编程:一种编程范式,指导开发者如何组织程序结构作用:在不惊动原始设计的基础上为其进行功能增强。连接点(JoinPoint):程序执行过程中的任意位置切入点(PointCut)ÿ…...

linux 配置java环境
1、上传jdk包到/usr/local/java目录下 2、解压jdk的tar包 tar -zxvf jdk-8u291-linux-x64.tar.gz 3、添加配置(环境变量) 注意:JAVA_HOME值为实际jdk路径 打开配置文件 vi /etc/profile 最下面添加: #set java environment JAVA_HOME/usr/…...

分布式事务基础入门
分布式事务基础入门 什么是分布式事务 什么是分布式事务? 首先理解什么是本地事务? 平常我们在程序中通过spring去控制事务是利用数据库本身的事务特性来实现的,因此叫数据库事务,由于应用主要靠关系数据库来控制事务࿰…...

白盒测试究竟怎么做
大家好,我是洋子 在进行日常测试的时候,我们大部分时间花在手动的功能测试上,功能测试又可称为手工测试,官方一点的学名叫黑盒测试,当然作为测试工程师,我们一般俗称点点点 黑盒测试是一种软件测试方法&am…...

EEG微状态的功能意义
导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构,这些结构能够最佳地解释自发EEG记录中随时间变化的差异。这四种结构被称为EEG微状态A、B、C和D类,分别与言语/语音、视觉、主观感受-自主加工和注意力重定…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...