iOS 练习项目 Landmarks (五):UISwitch 切换展示数据

news2024/11/20 0:30:24

iOS 练习项目 Landmarks (五):UISwitch 切换展示数据

  • iOS 练习项目 Landmarks (五):UISwitch 切换展示数据
    • 引入 Lookin
    • 优化项目结构
    • 纯代码方式重写主界面
    • 设置详情页的返回按钮的文本
    • Switch切换TableView展示数据
    • 更新 PlaceCellDelegate 协议
    • 设置 AppIcon

iOS 练习项目 Landmarks (五):UISwitch 切换展示数据

引入 Lookin

新建一个Podfile:

source 'https://xxx.git'
platform :ios, '17.5'
use_frameworks!
target 'Landmarks' do
  pod 'LookinServer', '1.2.2', :configurations => ['Debug']
end

从 source 中引入 LookinServer,版本为 1.2.2。

命令行输入:

pod install

编译报错:

Sandbox:rsync.sanba deny(1) file-write-create xxx

解决方法:Build Settings-Build Options-User Script Sandboxing 改为 NO。

在这里插入图片描述

User Script Sandboxing是一种安全策略,它通过创建一个受限制的执行环境来限制用户脚本的访问权限和资源使用。其主要目的是防止恶意代码或未经授权的用户脚本对系统文件、网络或其他敏感资源造成损害。

应用场景:在Xcode中,User Script Sandboxing可以确保用户自定义的脚本或工具在开发过程中不会意外地修改系统文件或访问敏感数据。在浏览器扩展或用户脚本中,Sandboxing可以确保这些脚本不会访问或修改它们不应该访问的网页内容或用户数据。

优化项目结构

删除 SceneDelegate.h 和 SceneDelegate.m,删除 Main.storyboard,删除项目配置中与 Main.storyboard 相关的东西,删除 Info.plist 的内容。

纯代码方式重写主界面

ViewController.h:

#import <UIKit/UIKit.h>
#import "PlaceCell.h"
#import "DetailViewController.h"

@interface ViewController : UIViewController
    <UITableViewDelegate, UITableViewDataSource, PlaceCellDelegate, DetailViewControllerDelegate>

@property (nonatomic, strong) UILabel *labelTitle;
@property (nonatomic, strong) UIView *dividerView1;
@property (nonatomic, strong) UILabel *labelFavor;
@property (nonatomic, strong) UISwitch *favoriteSwitch;
@property (nonatomic, strong) UIView *dividerView2;
@property (nonatomic, strong) UITableView *placeTable;

@property (nonatomic, strong) NSMutableArray *data; // 完整数据源
@property (nonatomic, strong) NSMutableArray *places; // 过滤数据源

- (void)initPlaces;

@end

界面实现:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    [self.view setBackgroundColor:UIColor.whiteColor];

    CGRect labelTitleFrame = CGRectMake(0, 0, 200, 80);
    CGRect dividerView1Frame = CGRectMake(0, 0, 300, 1);
    CGRect labelFavorFrame = CGRectMake(0, 0, 150, 50);
    CGRect favoriteSwitchFrame = CGRectMake(0, 0, 51, 31);
    CGRect dividerView2Frame = CGRectMake(0, 0, 300, 1);
    CGRect placeTableFrame = CGRectMake(0, 0, 400, 500);

    // 创建并设置 labelTitle
    self.labelTitle = [[UILabel alloc] initWithFrame:labelTitleFrame];
    // 设置应用标题的字体
    UIFont *labelTitleFont = [UIFont fontWithName:@"Helvetica-Bold" size:38];
    [self.labelTitle setFont:labelTitleFont];
    [self.labelTitle setText:@"Landmarks"];
    self.labelTitle.translatesAutoresizingMaskIntoConstraints = NO;

    // 创建并设置 dividerView1
    self.dividerView1 = [[UIView alloc] initWithFrame:dividerView1Frame];
    [self.dividerView1 setBackgroundColor:[[UIColor lightGrayColor] colorWithAlphaComponent:0.5]];
    self.dividerView1.translatesAutoresizingMaskIntoConstraints = NO;

    // 创建并设置 labelFavor
    self.labelFavor = [[UILabel alloc] initWithFrame:labelFavorFrame];
    // 设置标签的字体
    UIFont *labelFavorFont = [UIFont systemFontOfSize:18];
    [self.labelFavor setFont:labelFavorFont];
    [self.labelFavor setText:@"Favorites only"];
    self.labelFavor.translatesAutoresizingMaskIntoConstraints = NO;

    // 创建并设置 favoriteSwitch
    self.favoriteSwitch = [[UISwitch alloc] initWithFrame:favoriteSwitchFrame];
    self.favoriteSwitch.translatesAutoresizingMaskIntoConstraints = NO;
    // 添加目标-动作对
    [self.favoriteSwitch addTarget:self action:@selector(favoriteSwitchValueChanged:) forControlEvents:UIControlEventValueChanged];

    // 创建并设置 dividerView2
    self.dividerView2 = [[UIView alloc] initWithFrame:dividerView2Frame];
    [self.dividerView2 setBackgroundColor:[[UIColor lightGrayColor] colorWithAlphaComponent:0.5]];
    self.dividerView2.translatesAutoresizingMaskIntoConstraints = NO;

    // 创建并设置 placeTable
    self.placeTable = [[UITableView alloc] initWithFrame:placeTableFrame];
    [self.placeTable setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
    [self.placeTable setSeparatorColor:UIColor.lightGrayColor];
    self.placeTable.translatesAutoresizingMaskIntoConstraints = NO;
    // 将当前对象设置为 UITableView 对象的 dataSource
    [self.placeTable setDataSource:self];
    // 设置 UITableViewDelegate
    self.placeTable.delegate = self;
    // 需要创建新的单元格时,告诉 UITableView 对象要实例化哪个类
    [self.placeTable registerClass:[PlaceCell class] forCellReuseIdentifier:@"PlaceCellIdentfier"];
    self.placeTable.backgroundColor = [UIColor whiteColor];
    
    [self initPlaces];
    self.places = [NSMutableArray arrayWithArray:self.data];

    [self.view addSubview:self.labelTitle];
    [self.view addSubview:self.dividerView1];
    [self.view addSubview:self.labelFavor];
    [self.view addSubview:self.favoriteSwitch];
    [self.view addSubview:self.dividerView2];
    [self.view addSubview:self.placeTable];
    
    /* 添加约束 */
    [NSLayoutConstraint activateConstraints:@[
        [self.labelTitle.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:95],
        [self.labelTitle.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],
    ]];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.dividerView1.topAnchor constraintEqualToAnchor:self.labelTitle.bottomAnchor constant:10],
        [self.dividerView1.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],
        [self.dividerView1.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:0],
        [self.dividerView1.heightAnchor constraintEqualToConstant:1]
    ]];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.labelFavor.topAnchor constraintEqualToAnchor:self.dividerView1.bottomAnchor constant:0],
        [self.labelFavor.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],
        [self.labelFavor.heightAnchor constraintEqualToConstant:50]
    ]];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.favoriteSwitch.centerYAnchor constraintEqualToAnchor:self.labelFavor.centerYAnchor],
        [self.favoriteSwitch.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-20],
    ]];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.dividerView2.topAnchor constraintEqualToAnchor:self.labelFavor.bottomAnchor constant:0],
        [self.dividerView2.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:20],
        [self.dividerView2.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:0],
        [self.dividerView2.heightAnchor constraintEqualToConstant:1]
    ]];
    
    [NSLayoutConstraint activateConstraints:@[
        [self.placeTable.topAnchor constraintEqualToAnchor:self.dividerView2.bottomAnchor constant:0],
        [self.placeTable.widthAnchor constraintEqualToAnchor:self.view.widthAnchor],
        [self.placeTable.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor constant:0]
    ]];
}

用 Lookin 去查看各组件的位置,效果比较好:

在这里插入图片描述

设置详情页的返回按钮的文本

以前是Back,要改成Landmarks。

实际上这个返回按钮是导航条的 backBarButtonItem,新建一个 UIBarButtonItem,再设置即可:

self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Landmarks" style:UIBarButtonItemStylePlain target:nil action:nil];

Switch切换TableView展示数据

按 favorite 属性进行筛选,当 Switch 的状态为On时,PlaceTable 只显示收藏的景点,即 favorite=YES 的 Place 对象对应的 PlaceCell。

新增一个 Place 对象数组:data,将其作为完整数据源,而之前的 places 数组作为过滤数据源。修改 initPlaces 方法,从 plist 读的数据不存储在 places 数组里,转而存储在 data 数组里。

在 Switch 的 ValueChange 事件中,如果当前 Switch 的状态为 On,那么遍历 data 数组,将所有 favorite=YES 的 Place 对象插入 places 数组;否则,places = data。还是将 places 作为 PlaceCell 的数据源进行设置,最后别忘了 placeTable 要重新加载数据。

- (void)favoriteSwitchValueChanged:(UISwitch *)sender {
    if ([sender isOn])
    {
        [self.places removeAllObjects];
        for (Place *p in self.data)
        {
            if ([p favorite])
            {
                [self.places addObject:p];
            }
        }
    }
    else
    {
        self.places = [NSMutableArray arrayWithArray:self.data];
    }
    [self.placeTable reloadData];
}

更新 PlaceCellDelegate 协议

删除了 PlaceCellDelegate.h,协议声明放到 PlaceCell.h 里。

将可选方法:

- (void)updateFavorite:(BOOL)newFavorite atPlaceCell:(PlaceCell *)cell;

修改成:

- (void)placeCell:(PlaceCell *)cell updateFavorite:(BOOL)favorite;

其他相关代码也一起修改。

设置 AppIcon

用 AI 生成一个 1024*1024 分辨率的图片,放到 Assets 的 AppIcon 里即可。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通江银耳销售管理系统-计算机毕业设计源码15998

摘要 随着人们健康意识的增强&#xff0c;银耳这种传统的中药食材备受关注。而通江银耳是四川省通江县特产&#xff0c;中国国家地理标志产品。四川省通江县是银耳的发源地&#xff0c;中国银耳之乡&#xff0c;通江银耳因主产于此而得名&#xff0c;以其独到的质厚、肉嫩、易炖…

【linux高级IO(一)】理解五种IO模型

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux高级IO 1. 前言2. 重谈对…

Chrome插件分享-Stylus

简介 Stylus 是一个调整网页外观的用户样式管理器。它可以让您轻松为许多热门网站安装主题和皮肤。 这是 chrome 应用商店对Stylus插件的介绍&#xff0c;通俗一点讲&#xff0c;就是可以根据不同网站来定制网页的主题和皮肤&#xff0c;甚至可以去广告。 还有一个重点是&#…

高薪程序员必修课-java中 类加载器以及JVM类加载机制

前言 在Java中&#xff0c;类加载器&#xff08;ClassLoader&#xff09;是Java虚拟机&#xff08;JVM&#xff09;的一个重要组成部分&#xff0c;负责将.class文件加载到内存中并生成对应的Class对象。类加载器的主要任务是动态加载Java类&#xff0c;即在程序运行时根据需要…

刚办理的手机号被停用,你可能遇到这些问题了!

很多朋友都会遇到手机号被停用的情况&#xff0c;那么你知道你的手机号为什么会被停用吗&#xff1f;接下来&#xff0c;关于手机号被停用的问题&#xff0c;跟着小编一块来了解一下吧。 ​停机的两种形态&#xff1a; 1、第一个是局方停机&#xff0c;即语音、短信和流量都不…

Amazon SageMaker 机器学习之旅的助推器

一、前言 在当今的数字化时代&#xff0c;人工智能和机器学习已经成为推动社会进步的重要引擎。亚马逊云科技在 2023 re:Invent 全球大会上&#xff0c;宣布推出五项 Amazon SageMaker 新功能&#xff1a; Amazon SageMaker HyperPod 通过为大规模分布式训练提供专用的基础架构…

香橙派AIpro开发板评测:部署yolov5模型实现图像和视频中物体的识别

OrangePi AIpro 作为业界首款基于昇腾深度研发的AI开发板&#xff0c;自发布以来就引起了我的极大关注。其配备的8/20TOPS澎湃算力&#xff0c;堪称目前开发板市场中的顶尖性能&#xff0c;实在令人垂涎三尺。如此强大的板子&#xff0c;当然要亲自体验一番。今天非常荣幸地拿到…

Kubernetes基于helm安装 harbor

Kubernetes基于helm安装 harbor 之前harbor的安装都是借助docker完成一键安装部署&#xff0c;安装完成之后harbor组件均运行到一台机器上面&#xff0c;本文实践harbor在k8s环境中的部署。 准备工作 根据harbor官方要求&#xff1a; Kubernetes cluster 1.20Helm v3.2.0 …

kkFileView一款好用开源免费的文件在线预览项目

在这个数字化时代&#xff0c;我们每天都要跟各种文件打交道&#xff0c;但很多时候&#xff0c;文件预览却成了个头疼的问题&#xff0c;很多时候我们都希望能够在不下载文件的情况下&#xff0c;快速查看文件内容。 今天开源君就来分享一款文件在线预览项目 - kkFileView&am…

编译rust程序,并让它依赖低版本的GLIBC库

目录 方法一&#xff1a;在较低版本的linux系统里面编译更新centos源安装 gcc 方法二&#xff1a;静态编译 在linux环境下编译rust程序&#xff0c;编译好的程序会依赖你当前系统的GLIBC库&#xff0c;也就是说你的程序无法在使用更低版本GLIBC库的linux系统中运行。 查看当前系…

Java案例:完成用户登录

一案例要求&#xff1a; 二代码实现&#xff1a; Ⅰ package 重修;import java.util.Random; import java.util.Scanner;public class first {public static void main(String[] args) {javabean s1new javabean("张世杰","5201314");Scanner scnew Scan…

【Linux】Linux常用指令合集精讲,一篇让你彻底掌握(万字真言)

文章目录 一、文件与目录操作1.1 ls - 列出目录内容1.2 cd - 切换目录1.3 pwd - 显示当前目录1.4 mkdir - 创建目录1.5 rmdir - 删除空目录1.6 rm - 删除文件或目录1.7 cp - 复制文件或目录1.8 mv - 移动或重命名文件或目录1.9 touch - 创建空文件或更新文件时间戳 二、文件内容…

日期选取限制日期范围antdesign vue

限制选取的日期范围 效果图 <a-date-pickerv-model"dateTime"format"YYYY-MM-DD":disabled-date"disabledDate"valueFormat"YYYY-MM-DD"placeholder"请选择日期"allowClear />methods:{//回放日期选取范围限制&…

nginx 搭理禅道

1.安装nginx。 2.安装禅道。 3.nginx 配置文件 location /zentao/ { proxy_pass http://192.168.100.66/zentao/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-F…

论文解读StyleGAN系列——StyleGANv3

论文&#xff1a;Alias-Free Generative Adversarial Networks&#xff08;2021.06&#xff09; 作者&#xff1a;Tero Karras, Miika Aittala, Samuli Laine, Erik Hrknen, Janne Hellsten, Jaakko Lehtinen, Timo Aila 链接&#xff1a;https://arxiv.org/abs/2106.12423 代码…

高效使用 Guzzle:POST 请求与请求体参数的最佳实践

介绍 在现代爬虫技术中&#xff0c;高效发送 HTTP 请求并处理响应数据是关键步骤之一。Guzzle 是一个强大的 PHP HTTP 客户端&#xff0c;广泛应用于发送同步和异步请求。本文将介绍如何使用 Guzzle 发送 POST 请求&#xff0c;特别是如何传递请求体参数&#xff0c;并结合代理…

Windows 网络发现是什么意思?如何启用?

什么是 Windows 网络发现 Windows 网络发现是一项使计算机能够在本地网络中发现并与其他设备通信的功能。通过网络发现&#xff0c;用户可以在网络上轻松找到和访问其他计算机、打印机和共享资源。这对于家庭网络和小型办公室环境尤为重要&#xff0c;因为它简化了设备互联和资…

【RAG检索增强生成】MaxKB:构建企业级知识库问答系统(Ollama+Qwen2)

目录 引言1、MaxKB概述1.1 定义与目标1.2 特点与优势 2、MaxKB原理3、MaxKB架构4、基于MaxKBOllamaQwen2搭建本地知识库4.1 环境准备4.2 部署MaxKB4.3 部署Ollama4.4 部署运行qwen24.5 知识库配置4.5.1登录 MaxKB 系统4.5.2上传文档4.5.3设置分段规则 4.6 模型配置4.7 创建应用…

pytest-yaml-sanmu(七):使用fixture返回值

fixture 是 pytest 中非常重要的功能&#xff0c;大部分项目都可能会用到 fixture。 pytest 的内置标记 usefixtures 可以帮助用例自动的使用 fixture 1. 创建 fixture pytest 中的 fixtures 大致有两个用途 在用例执行之前、执行之后&#xff0c;自动的执行 通过 fixture …

如何在Qt使用uchardet库

如何在 Qt 中使用 uchardet 库 文章目录 如何在 Qt 中使用 uchardet 库一、简介二、uchardet库的下载三、在Qt中直接调用四、编译成库文件后调用4.1 编译工具下载4.2 uchardet源码编译4.3 测试编译文件4.4 Qt中使用 五、一些小问题5.1 测试文件存在的问题5.2 uchardet库相关 六…