【iOS】——知乎日报第五周总结

文章目录

  • 一、评论区展开与收缩
  • 二、FMDB库实现本地持久化
      • FMDB常用类:
      • FMDB的简单使用:
  • 三、点赞和收藏的持久化


一、评论区展开与收缩

有的评论没有被回复评论或者被回复评论过短,这时就不需要展开全文的按钮,所以首先计算被回复评论的文本高度,根据文本高度来决定是否隐藏展开全文的按钮。

CGSize constrainedSize = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
    NSDictionary *attributes = @{NSFontAttributeName: cell.replyLabel.font}; // label为要计算高度的UILabel控件
    CGRect textRect = [cell.replyLabel.text boundingRectWithSize:constrainedSize
                                         options:NSStringDrawingUsesLineFragmentOrigin
                                      attributes:attributes
                                         context:nil];
    CGFloat textHeight = CGRectGetHeight(textRect);
    if (textHeight > 100) {
        cell.foldButton.hidden = NO;
    } else {
        cell.foldButton.hidden = YES;
    }

要实现评论区的展开全文和收起,需要先实现评论区文本的自适应高度,接着我用数组来记录每个按钮的状态,如果为展开状态则为1,如果为收起状态则为0。通过数组中按钮的状态为按钮的selected属性做出选择并改变cell的高度。当我点击按钮时就改变该按钮在数组中的相应值。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && self.longComments != 0) {

        NSString* longStr = [self.discussModel.longCommentsArray[indexPath.row] content];
        NSString* longReplyStr = [self.discussModel.longCommentsArray[indexPath.row] reply_to][@"content"];
        CGSize constrainedSize = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font = [UIFont systemFontOfSize:18.0];
        NSDictionary *attributes = @{NSFontAttributeName: font}; // label为要计算高度的UILabel控件
        CGRect textRect = [longStr boundingRectWithSize:constrainedSize
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes
                                             context:nil];
        CGFloat textHeight = CGRectGetHeight(textRect);
        
        CGSize constrainedSize02 = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font02 = [UIFont systemFontOfSize:16.0];
        NSDictionary *attributes02 = @{NSFontAttributeName: font02}; // label为要计算高度的UILabel控件
        CGRect textRect02 = [longReplyStr boundingRectWithSize:constrainedSize02
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes02
                                             context:nil];
        CGFloat textHeight02 = CGRectGetHeight(textRect02);
        
        NSLog(@"长评论高度为:%f", textHeight);
        if ([self.discussModel.longButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            return textHeight + textHeight02 + 180;
        }
        return textHeight + 180;
    } else {
        NSString* shortStr = [self.discussModel.shortCommentsArray[indexPath.row] content];
        NSString* shortReplyStr = [self.discussModel.shortCommentsArray[indexPath.row] reply_to][@"content"];
        CGSize constrainedSize = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font = [UIFont systemFontOfSize:18.0];
        NSDictionary *attributes = @{NSFontAttributeName: font}; // label为要计算高度的UILabel控件
        CGRect textRect = [shortStr boundingRectWithSize:constrainedSize
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes
                                             context:nil];
        CGFloat textHeight = CGRectGetHeight(textRect);
        
        CGSize constrainedSize02 = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font02 = [UIFont systemFontOfSize:16.0];
        NSDictionary *attributes02 = @{NSFontAttributeName: font02}; // label为要计算高度的UILabel控件
        CGRect textRect02 = [shortReplyStr boundingRectWithSize:constrainedSize02
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes02
                                             context:nil];
        CGFloat textHeight02 = CGRectGetHeight(textRect02);
        
        NSLog(@"段评论高度为:%f", textHeight);
        if ([self.discussModel.shortButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            return textHeight + textHeight02 + 180;
        }
        return textHeight + 180;
    }  
}

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 && self.longComments != 0) {
        if (indexPath.row == 0) {
            cell.commentsNumLabel.text = [NSString stringWithFormat:@"%ld条长评", self.longComments];
        }
        cell.foldButton.tag = indexPath.row * 2 + 1;
        if ([self.discussModel.longButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            cell.foldButton.selected = YES;
            cell.replyLabel.numberOfLines = 0;
        } else {
            cell.foldButton.selected = NO;
            cell.replyLabel.numberOfLines = 2;
        }
}else {
        
        cell.foldButton.tag = indexPath.row * 2;
        if ([self.discussModel.shortButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            cell.foldButton.selected = YES;
            cell.replyLabel.numberOfLines = 0;
        } else {
            cell.foldButton.selected = NO;
            cell.replyLabel.numberOfLines = 2;
        }
- (void)pressFold:(UIButton*)button {
    DiscussCustomCell* cell = (DiscussCustomCell*)[[button superview] superview];
    if ([self.discussModel.longButtonSelectArray[(button.tag - 1) / 2] isEqualToString:@"1"]) {
        [self.discussModel.longButtonSelectArray replaceObjectAtIndex:((button.tag - 1) / 2) withObject:@"0"];
        [self.discussView.tableview reloadData];
    } else {
        [self.discussModel.longButtonSelectArray replaceObjectAtIndex:((button.tag - 1) / 2) withObject:@"1"];
        [self.discussView.tableview reloadData];
    }
    
    if ([self.discussModel.shortButtonSelectArray[button.tag / 2] isEqualToString:@"1"]) {
        [self.discussModel.shortButtonSelectArray replaceObjectAtIndex:(button.tag / 2) withObject:@"0"];
        [self.discussView.tableview reloadData];
    } else {
        [self.discussModel.shortButtonSelectArray replaceObjectAtIndex:(button.tag / 2) withObject:@"1"];
        [self.discussView.tableview reloadData];
    }
}

请添加图片描述

请添加图片描述

二、FMDB库实现本地持久化

FMDB是iOS平台的SQLite数据库框架,以OC的方式封装了SQLite的C语言API。

FMDB常用类:

FMDatabase:一个FMDatabase对象就代表一个单独的SQLite数据库用来执行SQL语句。
FMResultSet:使用FMDatabase执行查询后的结果集。
FMDatabaseQueue:用于在多线程中执行多个查询或更新,它是线程安全的。

FMDB的简单使用:

要使用FMDB库首先需要通过CocoaPods来安装这个第三方库

pod 'FMDB'

安装完成之后就可以进行使用了。

创建数据库

//获取数据库文件的路径
    NSString* doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

        NSString *fileName = [doc stringByAppendingPathComponent:@"collectionData.sqlite"];
    //获得数据库
    self.collectionDatabase = [FMDatabase databaseWithPath:fileName];
    //打开数据库
    if ([self.collectionDatabase open]) {
        BOOL result = [self.collectionDatabase executeUpdate:@"CREATE TABLE IF NOT EXISTS collectionData (mainLabel text NOT NULL, nameLabel text NOT NULL, imageURL text NOT NULL, networkURL text NOT NULL, dateLabel text NOT NULL, nowLocation text NOT NULL, goodState text NOT NULL, collectionState text NOT NULL, id text NOT NULL);"];
        if (result) {
            NSLog(@"创表成功");
        } else {
            NSLog(@"创表失败");
        }
    }

数据库增加数据

//插入数据
- (void)insertData {
    if ([self.collectionDatabase open]) {
        NSString *string = @"GenShen";
        BOOL result = [self.collectionDatabase executeUpdate:@"INSERT INTO collectionData (mainLabel, nameLabel, imageURL, networkURL, dateLabel, nowLocation, goodState, collectionState, id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", string, string, string, string, string, string, string, string, string];
        if (!result) {
            NSLog(@"增加数据失败");
        }else{
            NSLog(@"增加数据成功");
        }
        [self.collectionDatabase close];
    }
}

数据库修改数据

//修改数据
- (void)updateData {
    if ([self.collectionDatabase open]) {
        NSString* sql = @"UPDATE collectionData SET id = ? WHERE nameLabel = ?";
        BOOL result = [self.collectionDatabase executeUpdate:sql, @"114514",@"GenShen"];
        if (!result) {
                    NSLog(@"数据修改失败");
                } else {
                    NSLog(@"数据修改成功");
                }
                [self.collectionDatabase close];
    }
}

数据库删除数据

//删除数据
- (void)deleteData {
    if ([self.collectionDatabase open]) {
        NSString* sql = @"delete from collectionData WHERE collectionState = ?";
        BOOL result = [self.collectionDatabase executeUpdate:sql, @"爱玩原神"];
        if (!result) {
                    NSLog(@"数据删除失败");
                } else {
                    NSLog(@"数据删除成功");
                }
                [self.collectionDatabase close];
    }
}

数据库查询数据

//查询数据
- (void)queryData {
    if ([self.collectionDatabase open]) {
        FMResultSet* resultSet = [self.collectionDatabase executeQuery:@"SELECT * FROM collectionData"];
        while ([resultSet next]) {
                    NSString *mainLabel = [resultSet stringForColumn:@"mainLabel"];
                    NSLog(@"mainLabel = %@",mainLabel);
                    NSString *nameLabel = [resultSet stringForColumn:@"nameLabel"];
                    NSLog(@"nameLabel = %@",nameLabel);
                    NSString *imageURL = [resultSet stringForColumn:@"imageURL"];
                    NSLog(@"imageURL = %@",imageURL);
                    NSString *networkURL = [resultSet stringForColumn:@"networkURL"];
                    NSLog(@"networkURL = %@",networkURL);
                    NSString *dateLabel = [resultSet stringForColumn:@"dateLabel"];
                    NSLog(@"dateLabel = %@",dateLabel);
                    NSString *nowLocation = [resultSet stringForColumn:@"nowLocation"];
                    NSLog(@"nowLocation = %@",nowLocation);
                    NSString *goodState = [resultSet stringForColumn:@"goodState"];
                    NSLog(@"goodState = %@",goodState);
                    NSString *collectionState = [resultSet stringForColumn:@"collectionState"];
                    NSLog(@"collectionState = %@",collectionState);
                    NSString *id = [resultSet stringForColumn:@"id"];
                    NSLog(@"id = %@",id);
                }
                [self.collectionDatabase close];
    }
}

三、点赞和收藏的持久化

要实现点赞和收藏的持久化就需要用到前面所提到的FMDB库进行操作。在需要用到数据库的部分进行数据库的创建和一些基本操作例如增删改查。以收藏持久化为例子,当点击点赞收藏按钮的时候,进入到数据库查询函数进行查询,如果找到就将该数据进行删除然后将按钮状态设置为未选中状态。如果没有找到该数据就进行添加然后将按钮状态设置为选中状态

- (void)pressCollect:(UIButton*)button {
    
        NSString* collectionIdStr = [NSString stringWithFormat:@"%ld", self.idStr];
        int flag = [self queryCollectionData];
        if (flag == 1) {
            self.mainWebView.collectButton.selected = NO;
            [self deleteCollectionData:collectionIdStr];
        } else {
            self.mainWebView.collectButton.selected = YES;
            [self insertCollectionData:self.mainLabel andUrl:self.imageUrl andStr:collectionIdStr];
        }
}


当滑动切换页面请求新闻额外信息时也需要先进行判断当前点赞和收藏的按钮状态

[[ExtraManager sharedSingleton] ExtraGetWithData:^(GetExtraModel * _Nullable extraModel) {
        dispatch_async(dispatch_get_main_queue(), ^{
            int flag = [self queryLikesData];
            int collectFlag = [self queryCollectionData];
            self.mainWebView.discussLabel.text = [NSString stringWithFormat:@"%ld", extraModel.comments];
            self.mainWebView.likeLabel.text = [NSString stringWithFormat:@"%ld", extraModel.popularity];
            self.longComments = extraModel.long_comments;
            self.shortComments = extraModel.short_comments;
            if (flag == 1) {
                self.mainWebView.likeButton.selected = YES;
                NSInteger likesNum = [self.mainWebView.likeLabel.text integerValue];
                likesNum++;
                self.mainWebView.likeLabel.text = [NSString stringWithFormat:@"%ld", likesNum];
                NSString* likesIdStr = [NSString stringWithFormat:@"%ld", self.idStr];
                [self insertLikesData:likesIdStr];
            } else {
                self.mainWebView.likeButton.selected = NO;
            }
            if (collectFlag == 1) {
                self.mainWebView.collectButton.selected = YES;
            } else {
                self.mainWebView.collectButton.selected = NO;
            }
            
            NSLog(@"额外信息获取成功");
        });
        } andError:^(NSError * _Nullable error) {
            NSLog(@"额外信息获取失败");
        } andIdStr:self.idStr];

收藏数据库部分代码如下:

//创建
- (void)databaseInit {
    NSString* likesDoc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSLog(@"%@", likesDoc);
        NSString * likesFileName = [likesDoc stringByAppendingPathComponent:@"likesData.sqlite"];
    self.likesDatabase = [FMDatabase databaseWithPath:likesFileName];
    if ([self.likesDatabase open]) {
            BOOL result = [self.likesDatabase executeUpdate:@"CREATE TABLE IF NOT EXISTS likesData (id text NOT NULL);"];
            if (result) {
                NSLog(@"创表成功");
            } else {
                NSLog(@"创表失败");
            }
        }
    
    NSString* collectionDoc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSLog(@"%@", collectionDoc);
        NSString * collectionFileName = [collectionDoc stringByAppendingPathComponent:@"collectionData02.sqlite"];
    self.collectionDatabase = [FMDatabase databaseWithPath:collectionFileName];
    if ([self.collectionDatabase open]) {
            BOOL result  = [self.collectionDatabase executeUpdate:@"CREATE TABLE IF NOT EXISTS collectionData (mainLabel text NOT NULL, imageURL text NOT NULL, id text NOT NULL);"];
            if (result) {
                NSLog(@"创表成功");
            } else {
                NSLog(@"创表失败");
            }
        }
    
}
//增加
- (void)insertCollectionData:(NSString *)mainLabel andUrl:(NSString *)imageURL andStr:(NSString*)string {
    if ([self.collectionDatabase open]) {
        BOOL result = [self.collectionDatabase executeUpdate:@"INSERT INTO collectionData (mainLabel, imageURL, id) VALUES (?, ?, ?);", mainLabel, imageURL,string];
        if (!result) {
            NSLog(@"增加收藏数据失败");
        }else{
            NSLog(@"增加收藏数据成功");
        }
    }
    [self.collectionDatabase close];
}
//删除
- (void)deleteCollectionData:(NSString*)string {
    if ([self.collectionDatabase open]) {
        NSString *sql = @"delete from collectionData WHERE id = ?";
        BOOL result = [self.collectionDatabase executeUpdate:sql, string];
        if (!result) {
            NSLog(@"删除收藏数据失败");
        }else{
            NSLog(@"删除收藏数据成功");
        }
    }
    [self.collectionDatabase close];
}

//查询
- (int)queryCollectionData {
    if ([self.collectionDatabase open]) {
        FMResultSet* collectionResultSet = [self.collectionDatabase executeQuery:@"SELECT * FROM collectionData"];
        int count = 0;
        while ([collectionResultSet next]) {
            NSString *sqlIdStr = [NSString stringWithFormat:@"%@", [collectionResultSet objectForColumn:@"id"]];
            NSInteger sqlId = [sqlIdStr integerValue];
            NSLog(@"第 %d 个收藏数据库数据:%ld", count++ ,sqlId);
            if (self.idStr == sqlId) {
                [self.collectionDatabase close];
                return 1;
            }
           
        }
    }
    [self.collectionDatabase close];
    return 0;
}

请添加图片描述

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/165420.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode刷题-树】-- 572.另一棵树的子树

572.另一棵树的子树 方法:深度优先搜索暴力匹配 深度优先搜索枚举root中的每一个节点,判断这个点的子树是否与subroot相等 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right…

电子学会2023年6月青少年软件编程(图形化)等级考试试卷(四级)真题,含答案解析

青少年软件编程(图形化)等级考试试卷(四级) 一、单选题(共10题,共30分) 1. 下列积木运行后的结果是?( )(说明:逗号后面无空格) A.

读书笔记--从一到无穷大的关键金句和阅读感悟

借着休假,重新研读了十多年前读过的乔治.伽莫夫所著图书《从一到无穷大--ONE TWO THREE...INFINITY》,该书作为20世纪最经典的科普类图书之一,当时读的懵懵懂懂,现在重新阅读又有了不同的感受,再结合过去的科研工作&am…

计算机毕业设计选题推荐-内蒙古旅游微信小程序/安卓APP-项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

CBAM注意力机制(结构图加逐行代码注释讲解)

学CBAM前建议先学会SEnet(因为本篇涉及SEnet的重合部分会略加带过)->传送门 ⒈结构图 下面这个是自绘的,有些许草率。。。 因为CBAM机制是由通道和空间两部分组成的,所以有这两个模块(左边是通道注意力机制&#…

【MATLAB】全网唯一的11种信号分解+模糊熵(近似熵)联合算法全家桶

有意向获取代码,请转文末观看代码获取方式~ 大家吃一顿火锅的价格便可以拥有18种信号分解算法,绝对不亏,知识付费是现今时代的趋势,而且都是我精心制作的教程,有问题可随时反馈~也可单独获取某一算法的代码&#xff0…

【LeetCode刷题-树】--654.最大二叉树

654.最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 1.创建一个根节点,其值为 nums 中的最大值。 2.递归地在最大值 左边 的 子数组前缀上 构建左子树。 3.递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回…

【LeetCode刷题-树】--998.最大二叉树II

998.最大二叉树II /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

8.1 Windows驱动开发:内核文件读写系列函数

在应用层下的文件操作只需要调用微软应用层下的API函数及C库标准函数即可,而如果在内核中读写文件则应用层的API显然是无法被使用的,内核层需要使用内核专有API,某些应用层下的API只需要增加Zw开头即可在内核中使用,例如本章要讲解…

SQL单表复杂查询where、group by、order by、limit

1.1SQL查询代码如下&#xff1a; select job as 工作类别,count(job) as 人数 from tb_emp where entrydate <2015-01-01 group by job having count(job) > 2 order by count(job) limit 1,1where entrydate <‘2015-01-01’ 表示查询日期小于2015-01-01的记录…

Python大数据之linux学习总结——day11_ZooKeeper

ZooKeeper ZK概述 ZooKeeper概念: Zookeeper是一个分布式协调服务的开源框架。本质上是一个分布式的小文件存储系统 ZooKeeper作用: 主要用来解决分布式集群中应用系统的一致性问题。 ZooKeeper结构: 采用树形层次结构&#xff0c;ZooKeeper树中的每个节点被称为—Znode。且树…

随机过程-张灏

文章目录 导论随机过程相关 学习视频来源&#xff1a;https://www.bilibili.com/video/BV18p4y1u7NP?p1&vd_source5e8340c2f2373cdec3870278aedd8ca4 将持续更新—— 第一次更新&#xff1a;2023-11-19 导论 教材&#xff1a;《随机过程及其应用》陆大絟.张颢 参考&…

X3DAudio1_7.dll丢失原因,X3DAudio1_7.dll丢失怎样解决分享

X3DAudio1_7.dll是一款由微软公司开发的音频处理库&#xff0c;主要用于实现三维音频效果。这个库主要应用于游戏开发、多媒体应用等领域&#xff0c;它可以使得音频更加真实、自然地表现出空间感。如果在使用过程中遇到X3DAudio1_7.dll丢失的问题&#xff0c;可以尝试以下五个…

指南:关于帮助中心需要注意的一些细节

在现代商业环境中&#xff0c;帮助中心已经成为企业提供客户支持和解决问题的重要方式之一。然而&#xff0c;建立一个高效的帮助中心并不简单。除了选择合适的软件平台和工具之外&#xff0c;还需要注意一些细节&#xff0c;以确保能够真正帮助客户并提高客户满意度。 | 1.设计…

辅助解决小白遇到的电脑各种问题

写这个纯属是为了让电脑小白知道一些电脑上的简单操作&#xff0c;勿喷&#xff01;&#xff01;&#xff01; 一&#xff1a;当小白遇到电脑程序不完全退出怎么办&#xff1f; 使用软件默认的退出方式 此处拿百度网盘举例&#xff1a; 用户登录网盘后&#xff1a; 如果直接点…

spring常见面试题总结

1、spring是什么 Spring&#xff1a;是一个轻量级的IOC和AOP的java开发框架&#xff0c;为了简化企业级开发而生。核心就是控制反转和面向切面编程。 IOC&#xff1a;控制反转&#xff08;Inverse of Control&#xff09;&#xff0c;以前项目都是在哪儿用到对象 在哪儿new&a…

Vite - 静态资源处理 - json文件导入

直接就说明白了 vite 中对json 文件直接当作一个模块来解析。 可以直接导入使用&#xff01; 可以直接导入使用&#xff01; 可以直接导入使用&#xff01;json文件中的key&#xff0c;直接被作为一个属性&#xff0c;可以单独被导入。 因此&#xff0c;导入json文件有两种方式…

Rust与其他语言对比:优势在哪里?

大家好&#xff01;我是lincyang。 今天&#xff0c;我们将深入探讨Rust语言与其他编程语言比较的优势&#xff0c;并通过具体的代码示例和性能数据来加深理解。 Rust与其他语言的比较 1. 内存安全性 Rust&#xff1a;采用所有权系统&#xff0c;编译器在编译时检查内存安全…

自动驾驶学习笔记(十)——Cyber通信

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo Beta宣讲和线下沙龙》免费报名—>传送门 文章目录 前言 Cyber通信 编写代码 编译程序 运行…

AI绘画使用Stable Diffusion(SDXL)绘制三星堆风格的图片

一、前言 三星堆文化是一种古老的中国文化&#xff0c;它以其精湛的青铜铸造技术闻名&#xff0c;出土文物中最著名的包括青铜面具、青铜人像、金杖、玉器等。这些文物具有独特的艺术风格&#xff0c;显示了高度的工艺水平和复杂的社会结构。 青铜面具的巨大眼睛和突出的颧骨&a…