当前位置: 首页 > news >正文

学习HM微博项目第10天

步骤:发微博12-表情键盘06-点击表情 -> 发微博13-表情键盘07-插入表情和封装textView -> 发微博14-表情键盘08-长按表情 -> 发微博15-表情键盘09-最近表情 -> 发微博16-表情键盘10-最近表情完善

发微博12-表情键盘06-点击表情

APP的演示动画:

分析:当触发表情按钮的点击事件时,会出现相应表情的放大镜。

在HMPageEmotionView(scrollView上每一页上的表情内容)类的setEmotion:方法中,监听表情按钮点击,如下:

其中,btnClick:方法如下:

 

说明:

  1. HMEmotionButton封装了表情按钮的细节,一个HMEmotionButton对应一个HMEmotion。如下:

 2.HMEmotionPopView封装了表情按钮的放大镜的细节,并且懒加载。如下:

3.由于放大镜界面固定,所以采用xib加载。如下: 

补充:instancetype表明返回类型与调用该类方法的对象类型相同。

发微博13-表情键盘07-插入表情和封装textView

APP的演示动画:

 

分析:当点击表情按钮时,会发出通知,将表情数据传递给composeViewController的textView上,点击右下角的删除按钮可以删除已经插入的表情或文字。

在HMPageEmotionView中,完善btnClick:方法,延迟0.2s让popView自动消失,并且发出通知给composeViewController的textView是哪个按钮响应了点击事件。如下:

说明:由composeViewController的textView监听该通知,如下:

 

其中,emotionDidSelect:方法,具体代码如下:

 

在emotionDidSelect:方法中调用的insertEmotion:方法是HMEmotionTextView(继承自HMTextView)对插入表情细节的封装,如下:

 

其中insertAttributedText:方法是基于UITextView的category(扩展),如下:

 

在HMPageEmotionView中的initWithFrame:方法初始化删除按钮,如果没有设置删除按钮的frame,删除按钮会在pageView的subviews的第一个,截图如下:

为了解决这种情况,需要完善layoutSubviews:方法,让遍历subviews从1开始,如下: 

参照表情选中的通知,要实现删除按钮的功能,也要发出通知,如下: 

 

UITextView遵守的UIKeyInput协议上有一个很实用的方法,用于删除文字,如下: 

发微博14-表情键盘08-长按表情

APP的演示动画:

分析:在整个pageView上添加长按手势监听功能,只要手指长按表情按钮,表情按钮就会显示相应的放大镜。

在HMPageViewController的initWithFrame:方法中,添加长按手势,如下:

其中,longPressPageView:方法,具体代码如下: 

说明:
1.通过手指位置找对应的表情按钮的emotionButtonWith:方法如下:

 

2.showFrom:方法是HMEmotionPopView类中对显示popView详细代码的封装,同时改进了之前HMEmotionPopView类中的代码,删除了之前的emotion属性,如下:

3.完善btnClick:方法,如下:

 

发微博15-表情键盘09-最近表情

APP的演示动画:

分析:点击表情按钮,除了会发出通知,还会存储表情数据到沙盒中(归档),然后在”最近“上加载沙盒中的表情数据(ps:懒加载和”最近“按钮的点击事件都要加载沙盒中的表情数据,保证每次到”最近“界面能及时更新表情数据)。

参照账号登陆工具类,表情数据也要新建一个工具类,如下:

在HMPageEmotionView的selectEmotion:方法中,将表情数据存储到沙盒里,如下:

 

在HMEmotionKeyboard类的recentEmotionView懒加载和HMEmotionTabBarDeleage代理方法中的”最近“都要加载沙盒里的表情数据,如下: 

 

注意:
为了保证切换到”最近“时,表情数据能及时并且以正确的位置显示出来,需要对HMEmotionListView的setEmotion:方法进行完善,如下: 

发微博16-表情键盘10-最近表情完善

仔细观察之前的”最近“,相同的表情会重复出现,明显不符合常理。所有对其进行改进。

APP的演示动画:

 

分析:”最近“上相同的表情不会重复出现,并且被点击的表情会自动排在最前面。

在前文中,有两处地方加载了沙盒子的表情数据,意味着有两个表情数组,实际上只需要一个表情数组即可,所以对表情工具类进行改进,如下:

说明:
1.删除重复的表情,系统方法removeObject只能删除同一个内存地址的模型,不能满足要求。我们要删除的是内存地址不同的表情模型但是模型里的数据却相同。为此,可以在HMEmotion类重写isEqual方法,如下:

2.归档解档需要HMEmotion表情模型遵守NSCoding协议,并实现initWithCoder:
和encodeWithCoder:方法,如下: 

更轻松的解决方法是导入MJExtension框架,实现MJCodingImplementation即可,如下: 

3.加载沙盒中的表情数据,返回一个表情数组的方法现在只需要在懒加载中即可,如下: 

4.在”最近“中,点击表情,会即时更新”最近“上的表情数据,这是因为选中表情发出了通知,触发了加载表情数组的方法。如下: 

相关文章:

学习HM微博项目第10天

步骤:发微博12-表情键盘06-点击表情 -> 发微博13-表情键盘07-插入表情和封装textView -> 发微博14-表情键盘08-长按表情 -> 发微博15-表情键盘09-最近表情 -> 发微博16-表情键盘10-最近表情完善 发微博12-表情键盘06-点击表情 APP的演示动画&#xff…...

0204强连通性-有向图-数据结构和算法(Java)

文章目录1 概述2 强连通分量2.1 定义2.2 Kosaraju算法2.2.1 算法实现2.2.2算法测试2.2.3 算法理解3 强连通性结语1 概述 定义。如果2个顶点是相互可达的,则称它们为强连通的。如果一幅有向图中的任意两个顶点都是强连通的,则称这幅有向图也是强连通的。 …...

ElasticSearch集群

5.2 IK分词器简介 IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目Lucene为应用主体的,结合词典分词和文法分析算法的中文分…...

音视频基础概念(6)——视频基础

网上冲浪时,我们会接触到网络流媒体和本地视频文件。常见的视频文件格式有MP4、MKV、AVI等。在流媒体网站上看见视频常用的协议有HTTP、RTSP、RTMP、HLS等。视频技术较为复杂,包括视频封装、视频编解码、视频播放和视频转码等内容。1 视频基础概念当下市…...

【Python网络蜘蛛】基础 - 多线程和多进程的基本原理

文章目录多线程和多进程的基本原理多线程的含义并发和并行Python中的多线程和多进程多线程和多进程的基本原理 在编写爬虫程序的时候,为了提高爬取效率,我们可能会同时运行多个爬虫任务,其中同样涉及多进程和多线程。 多线程的含义 先了解一…...

linux C/C++文件路径操作

标题1、 access函数查找文件夹是否存在/文件是否有某权限 头文件&#xff1a; 在windows环境下头文件为&#xff1a; #include <io.h> 在linux环境下头文件为&#xff1a; #include <unistd.h> 函数原型&#xff1a; int access(const char* _Filename, int _Acce…...

Baumer工业相机堡盟相机如何使用BGAPI SDK和Opencv联动实现图像转换成视频(C#)

Baumer工业相机堡盟相机如何使用BGAPI SDK和Opencv联动实现图像转换成视频Baumer工业相机Baumer工业相机SDK技术背景代码分析第一步&#xff1a;先引用OpenCV库第二步&#xff1a;引用图像文件夹生成视频工业相机图像通过OpenCV转为视频的优点工业相机图像转为视频的行业应用​…...

Redis常用命令以及如何在Java中操作Redis

前言Redis是一个基于内存的key-value结构数据库&#xff0c;是互联网技术领域使用最为广泛的存储中间件。Redis基于内存存储&#xff0c;读写性能高&#xff0c;适合存储热点数据&#xff08;热点商品、资讯、新闻&#xff09;。Redis是一个开源的内存中的数据结构存储系统&…...

ASEMI代理AD7980BRMZRL7原装ADI(亚德诺)车规级AD7980BRMZRL7

编辑&#xff1a;ll ASEMI代理AD7980BRMZRL7原装ADI&#xff08;亚德诺&#xff09;车规级AD7980BRMZRL7 型号&#xff1a;AD7980BRMZRL7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;MSOP-10 批号&#xff1a;2023 安装类型&#xff1a;表面贴装型 AD7980BRMZRL7 汽车…...

leetcode141:环形链表

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;…...

lattice diamond软件使用

1.diamond软件破解&#xff1a; lisence坚果云下载&#xff1b;或者这个博主操作环境变量设置&#xff1a; 2. 调用IP 有两种方式&#xff0c;依据芯片或者软件版本改变。 传统的IPexpress&#xff0c;每个IP单独例化。 新出的Clarity&#xff0c;多个IP在同一个顶层内调用…...

scala泛型

目录 类型参数 泛型函数&#xff1a; 协变&#xff0c;逆变&#xff0c;不变 泛型上下限&#xff1a; 上下文限定&#xff1a; 泛型是一种类型参数&#xff0c;该类型参数可以用在类、接口和方法中&#xff0c;分别被称为泛型类、泛型接口、泛型方法 类型参数 调用时不指定…...

程序员与ChatGPT的日常问答

程序员与ChatGPT的日常问答GPT3.5与GPT4.0能力对比技术问题工具问题编解码问题其他问题本文记录下调教ChatGPT的日常。 GPT3.5与GPT4.0能力对比 Q&#xff1a;采用同一个问题提问&#xff0c;对比下GPT3.5和GPT4.0的能力区别&#xff0c;比如&#xff1a;帮我列一个小白入门音频…...

如何创建高效的Prompt和ChatGPT等大语言模型AI对话

大语言模型&#xff0c;如OpenAI的GPT-4&#xff0c;是一种基于深度学习技术的自然语言处理工具&#xff0c;它可以理解自然语言并为用户提供有价值的回答。然而&#xff0c;要从大语言模型中获得高质量的回答&#xff0c;你需要学会如何高效地提问。本文将从原理出发&#xff…...

043:cesium加载Bing地图(多种形式)

第043个 点击查看专栏目录 本示例的目的是介绍如何在vue+cesium中加载加载Bing地图。这里显示4种形式的地图,分别为:AERIAL、ROAD、CANVAS_DARK、AERIAL_WITH_LABELS。参考后面的API,还有其他几种形式。 直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果. 文章…...

vscode代码片段生成

在刚学习vue的时候&#xff0c;有些代码片段是经常写的&#xff0c;在vscode中写一个代码片段可以帮助快速生成。 生成步骤&#xff1a; VSCode中的代码片段有固定的格式&#xff0c;所以我们一般会借助于一个在线工具来完成。 具体的步骤如下: 第一步&#xff0c;复制自己需…...

数据规整:聚合、合并和重塑

目录一、层次化索引重排与分级排序根据级别汇总统计二、合并数据集数据库风格的DataFrame合并索引上的合并轴向连接合并重叠数据三、重塑和轴向旋转重塑层次化索引将“长格式”旋转为“宽格式”将“宽格式”旋转为“长格式”一、层次化索引 层次化索引&#xff08;hierarchica…...

开心档之C++ 信号处理

C 信号处理 目录 C 信号处理 signal() 函数 实例 raise() 函数 实例 信号是由操作系统传给进程的中断&#xff0c;会提早终止一个程序。在 UNIX、LINUX、Mac OS X 或 Windows 系统上&#xff0c;可以通过按 CtrlC 产生中断。 有些信号不能被程序捕获&#xff0c;但是下表…...

ChatGPT惨遭围剿?多国封杀、近万人联名抵制……

最近&#xff0c;全世界燃起一股围剿ChatGPT的势头。由马斯克、图灵奖得主Bengio等千人联名的“暂停高级AI研发”的公开信&#xff0c;目前签名数量已上升至9000多人。除了业内大佬&#xff0c;欧盟各国和白宫也纷纷出手。 最早“动手”的是意大利&#xff0c;直接在全国上下封…...

SpringBoot监听器

1.寻找spring.factories配置文件对应的监听器&#xff0c;主要要写监听器的全路径名&#xff0c;不然反射会报错 SpringBoot底层是如何读取META-INF/spring.factories的配置的&#xff1f; 1.遍历所有jar下的META-INF/spring.factories配置文件 2.读取配置文件下的所有属性&a…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...