「OC」UI练习(一)—— 登陆界面

news2025/1/17 0:58:56

「OC」登陆界面

明确要求

一个登陆界面的组成,用户名提示以及输入框,密码提示提示以及输入框,登陆按钮,以及注册按钮,根据以上要求我们将我们的组件设置为成员变量。

//viewControl.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (nonatomic) UILabel *lUserName;
@property (nonatomic) UILabel *lPassword;

@property (nonatomic) UITextField *tsUserName;
@property (nonatomic) UITextField *stPassword;

@property (nonatomic) UIButton *btnLogin;
@property (nonatomic) UIButton *btnRegister;

@end

界面设置

根据以上的组件,我们可以将组件进行编排,代码如下,可根据自身审美进行相关的排版

//viewControl.m
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    _lUserName = [[UILabel alloc] initWithFrame:CGRectMake(20, 200, 80, 40)];
    _lUserName.text = @"用户名:";
    _lUserName.font = [UIFont systemFontOfSize:20];
    _lUserName.textAlignment = NSTextAlignmentLeft;
    
    _lPassword = [[UILabel alloc] initWithFrame:CGRectMake(20, 260, 80, 40)];
    _lPassword.text = @"密码:";
    _lPassword.font = [UIFont systemFontOfSize:20];
    _lPassword.textAlignment = NSTextAlignmentLeft;
    
    _tsUserName = [[UITextField alloc] initWithFrame:CGRectMake(120, 200, 180, 40)];
    _tsUserName.placeholder = @"请输入用户名";
    
    _stPassword = [[UITextField alloc] initWithFrame:CGRectMake(120, 260, 180, 40)];
    _stPassword.placeholder = @"请输入密码";
    _stPassword.borderStyle = UITextBorderStyleRoundedRect;
    _stPassword.secureTextEntry = YES;
    
    _btnLogin = [[UIButton alloc] initWithFrame:CGRectMake(100, 400, 80, 40)];
    _btnLogin.backgroundColor = [UIColor redColor];
    [_btnLogin setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [_btnLogin setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
    [_btnLogin setTitle:@"登录" forState:UIControlStateNormal];
    [_btnLogin addTarget:self action:@selector(loginButtonTapped) forControlEvents:UIControlEventTouchUpInside];
        
    _btnRegister = [[UIButton alloc] initWithFrame:CGRectMake(200, 400, 80, 40)];
    _btnRegister.backgroundColor = [UIColor redColor];
    [_btnRegister setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [_btnRegister setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
    [_btnRegister setTitle:@"注册" forState:UIControlStateNormal];
    [_btnRegister addTarget:self action:@selector(registerButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:_lUserName];
    [self.view addSubview:_lPassword];
    [self.view addSubview:_btnLogin];
    [self.view addSubview:_btnRegister];
    [self.view addSubview:_stPassword];
    [self.view addSubview:_tsUserName];
}

实际界面展示如下

image-20240604214841246

功能实现

由两个按钮注册和登陆可以知道,我们需要实现两个功能登陆和注册,我们先从注册开始

注册

由于我们想要保存多个账号和密码,在本地我们可以直接通过文件操作来进行实现,此处我选择使用SFileHandle进行文件的修改。我们方便我们后面登陆的读取我们还应该尽量让账号和密码的存储具有一定的格式。

//viewControl.m
-(void)registerButtonTapped {
    NSString *username = _tsUserName.text;
    NSString *password = _stPassword.text;
        
        
    // 清空账号和密码字段
    _tsUserName.text = @"";
    _stPassword.text = @"";
    // 构造要写入文件的内容
    NSString *newUserData = [NSString stringWithFormat:@"%@,%@\n", username, password];
    // 写入文件
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:@"/Users/bb/Desktop/NSString/JC登陆/文档.txt"];
  //如果路径文件存在则进行操作
    if (fileHandle) {
        // 将文件指针移动到文件末尾
        [fileHandle seekToEndOfFile];
        
        // 将数据写入文件
        [fileHandle writeData:[newUserData dataUsingEncoding:NSUTF8StringEncoding]];
      
        // 关闭文件
        [fileHandle closeFile];
        
        // 注册成功提示
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"注册成功" message:@"您已成功注册新用户" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
        [alert addAction:okAction];
        [self presentViewController:alert animated:YES completion:nil];
    } else {
        // 文件操作失败提示
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"注册失败" message:@"无法写入用户数据" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
        [alert addAction:okAction];
        [self presentViewController:alert animated:YES completion:nil];
    }
}

在此之外,我们可以尽量规范用户的账号密码的格式和长度,于是对以上程序进行改进,完整的注册功能如下

-(void)registerButtonTapped {
    NSString *username = _tsUserName.text;
    NSString *password = _stPassword.text;
    
    // 清空账号和密码字段
    _tsUserName.text = @"";
    _stPassword.text = @"";
  
    // 检查用户名和密码是否满足要求
    if (![self validateUsername:username] || ![self validatePassword:password]) {
        // 用户名或密码不满足要求,显示错误提示
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"注册失败" message:@"用户名或密码不符合要求" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
        [alert addAction:okAction];
        [self presentViewController:alert animated:YES completion:nil];
        return;
    }
        
    // 构造要写入文件的内容
    NSString *newUserData = [NSString stringWithFormat:@"%@,%@\n", username, password];
    // 写入文件
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:@"/Users/bb/Desktop/NSString/JC登陆/文档.txt"];
    if (fileHandle) {
        // 将文件指针移动到文件末尾
        [fileHandle seekToEndOfFile];
        
        // 将数据写入文件
        [fileHandle writeData:[newUserData dataUsingEncoding:NSUTF8StringEncoding]];
        
        // 清空账号和密码字段
        _tsUserName.text = @"";
        _stPassword.text = @"";
      
        // 关闭文件
        [fileHandle closeFile];
        
        // 注册成功提示
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"注册成功" message:@"您已成功注册新用户" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
        [alert addAction:okAction];
        [self presentViewController:alert animated:YES completion:nil];
    } else {
        // 文件操作失败提示
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"注册失败" message:@"无法写入用户数据" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
        [alert addAction:okAction];
        [self presentViewController:alert animated:YES completion:nil];
    }
}
- (BOOL)validateUsername:(NSString *)username {
    // 在这里添加用户名的验证规则,例如:
    // 用户名必须包含至少 6 个字符,且只能包含字母和数字
    NSCharacterSet *allowedCharacters = [NSCharacterSet alphanumericCharacterSet];
    if (username.length < 6 || ![username rangeOfCharacterFromSet:allowedCharacters].length) {
        return NO;
    }
    return YES;
}

- (BOOL)validatePassword:(NSString *)password {
    // 在这里添加密码的验证规则,例如:
    // 密码必须包含至少 8 个字符,且包含至少一个大写字母和一个数字
    NSCharacterSet *uppercaseCharacters = [NSCharacterSet uppercaseLetterCharacterSet];
    NSCharacterSet *digitCharacters = [NSCharacterSet decimalDigitCharacterSet];
    if (password.length < 8 || ![password rangeOfCharacterFromSet:uppercaseCharacters].length || ![password rangeOfCharacterFromSet:digitCharacters].length) {
        return NO;
    }
    return YES;
}

image-20240604221416111

登陆功能

登陆功能其实就是从文件当中,找到相关的账号密码,我们要注意的就是如何从文件之中读取正确的内容,与用户输入的内容进行匹配,我们就可以多加使用NSString之中方便的相关方法来进行操作。当我们登陆成功的时候,我们就将JCHome这个控制其弹出。

我们需要进行视窗弹出时,需要进行一些细节的实现

//SceneDelegate.m的内容
#import "SceneDelegate.h"
#import "ViewController.h"
@interface SceneDelegate ()

@end

@implementation SceneDelegate


- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc]init] ];
    // 将导航控制器设置为窗口的根视图控制器
    self.window.rootViewController = navigationController;
    self.window.frame = [UIScreen mainScreen].bounds;
    [self.window makeKeyAndVisible];
}
______________________________________________________________________________________________________________________________
//JCHome.h
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface JCHome : UIViewController
@property (nonatomic, copy) NSString *userName;
@property (nonatomic, strong) UILabel *welcomeLabel;
@end

NS_ASSUME_NONNULL_END
______________________________________________________________________________________________________________________________
//JCHome.m
#import "JCHome.h"

@interface JCHome ()

@end

@implementation JCHome

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor redColor];
    _welcomeLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, CGRectGetWidth(self.view.frame) - 40, 40)];
    _welcomeLabel.textAlignment = NSTextAlignmentCenter;
    _welcomeLabel.font = [UIFont systemFontOfSize:24];
    _welcomeLabel.text = [NSString stringWithFormat:@"欢迎,%@", self.userName];
    
    [self.view addSubview:_welcomeLabel];
}

以下是登陆功能的实现

//viewControl.m
-(void)loginButtonTapped {
    NSString *username = _tsUserName.text;
    NSString *password = _stPassword.text;
    
    // 在这里可以进行登录验证逻辑,比如与文件中的数据进行比较
    
    // 从文件中读取数据
    NSString *fileData = [NSString stringWithContentsOfFile:@"/Users/bb/Desktop/NSString/JC登陆/文档.txt" encoding:NSUTF8StringEncoding error:nil];
    
    // 按行分割数据
    NSArray *lines = [fileData componentsSeparatedByString:@"\n"];
    
    for (NSString *line in lines) {
        // 按照特定的规则解析每行数据,比如使用逗号分隔字段
        NSArray *fields = [line componentsSeparatedByString:@","];
        
        // 获取用户名和密码字段
        NSString *storedUsername = fields[0];
        NSString *storedPassword = fields[1];
        
        if ([storedUsername isEqualToString:username] && [storedPassword isEqualToString:password]) {
            // 登录成功
            NSLog(@"登陆成功");
            JCHome *homeVC = [[JCHome alloc] init];
            homeVC.userName = username; // 将用户名传递给下一个界面,实现多界面传值

            [self.navigationController pushViewController:homeVC animated:YES];
            return;
        }
    }
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"登陆失败" message:@"账号或密码错误!" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
    [alert addAction: okAction];
    [self presentViewController:alert animated:YES completion:nil];
    
}


如果登陆成功则会弹出下一个界面

image-20240604223806253

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

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

相关文章

Kimichat使用案例013:用kimichat批量识别出图片版PDF文件中的文字内容

文章目录 一、介绍二、具体操作三、信息识别一、介绍 图片版的PDF文件,怎么才能借助AI工具来提取其中全部的文字内容呢? 第一步:将PDF文件转换成图片格式 具体方法参见文章: Kimichat使用案例011:用kimichat将PDF自动批量分割成多个图片(零代码编程) 第二步:识别图片中…

Go模板页面浏览器显示HTML源码问题

<!--* Title: This is a file for ……* Author: JackieZheng* Date: 2024-06-09 17:00:01* LastEditTime: 2024-06-09 17:01:12* LastEditors: Please set LastEditors* Description:* FilePath: \\GoCode\\templates\\index.html --> <!DOCTYPE html> <html …

【安装笔记-20240610-Linux-免费域名服务之eu.org】

安装笔记-系列文章目录 安装笔记-20240610-Linux-免费域名服务之eu.org 文章目录 安装笔记-系列文章目录安装笔记-20240610-Linux-免费域名服务之eu.org 前言一、软件介绍名称&#xff1a;eu.org主页官方介绍 二、安装步骤测试版本&#xff1a;openwrt-23.05.3-x86-64注册填写…

Java基础——多线程(一)

概念 线程和进程 进程&#xff1a;进程是程序的基本执行实体 线程&#xff1a;线程是操作系统能够进行运算调度的最小单位&#xff0c;它被包含在进程之中&#xff0c;是进程的实际运作单位 简单理解&#xff1a;应用软件中互相独立&#xff0c;可以同时运行的功能。多线程可以…

C++ | Leetcode C++题解之第144题二叉树的前序遍历

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> preorderTraversal(TreeNode *root) {vector<int> res;if (root nullptr) {return res;}TreeNode *p1 root, *p2 nullptr;while (p1 ! nullptr) {p2 p1->left;if (p2 ! nullptr) {…

Nginx配置详细解释:(4)高级配置

目录 1.网页的状态页 2.Nginx第三方模块(echo) 3.变量 4.自定义访问日志 5.Nginx压缩功能 6.https功能 7.自定义图标 Nginx除了一些基本配置外&#xff0c;还有一些高级配置&#xff0c;如网页的状态&#xff0c;第三方模块需要另外安装&#xff0c;支持变量&#xff0c…

SpringTask-Timer实现定时任务

1、Timer 实现定时任务 1.1、JDK1.3 开始推出定时任务实现工具。 1.2、API 执行代码 public static void main(String[] args) throws ParseException {Timer timer new Timer();String str"2024-06-10 23:24:00";Date date new SimpleDateFormat("yyyy-MM…

【docker】日志

ocker 日志相关的操作主要涉及查看、管理和理解容器的日志输出。以下是一些常用的 Docker 日志命令和选项&#xff1a; 查看日志 docker logs container_id_or_name&#xff1a;获取指定容器的日志。docker logs -f container_id_or_name&#xff1a;跟随&#xff08;实时输出…

idea开发java高校社团推广管理系统springboot框架web结构java编程计算机网页LayUI技术

一、源码特点 java 高校社团推广管理系统是一套完善的完整信息系统&#xff0c;结合java web开发springboot框架和LayUI框架完成本系统 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 前段主要…

使用Vue CLI在其他磁盘创建项目出现错误及解决

Vue CLI是Vue.js官方推出的脚手架工具&#xff0c;可以帮我们快速的创建Vue项目框架。 我们创建Vue项目时一般默认都是在C盘&#xff0c;但由于某些因素我们需要在其他磁盘上创建Vue项目。 通过“winr”打开终端时默认位置都是C盘&#xff0c;但是Vue CLI不接受绝对路径作为参…

C++ | Leetcode C++题解之第143题重排链表

题目&#xff1a; 题解&#xff1a; class Solution { public:void reorderList(ListNode* head) {if (head nullptr) {return;}ListNode* mid middleNode(head);ListNode* l1 head;ListNode* l2 mid->next;mid->next nullptr;l2 reverseList(l2);mergeList(l1, l…

OpenCV 双目三角法计算点云

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 基于三角法计算点坐标的过程类似于我们人类眼睛观察事物的过程: 如上图所示,通过两个相机观察到同一位置,我们可以通过两个相机得到这一位置的投影坐标 ( u r , v r ) , ( u l , v l )

IDEA:配置Golang的开发环境

1、下载&安装 进入GO的官网下载对应的GO 我们可以下载安装版&#xff0c;不过本人习惯下载解压版&#xff0c;这个因个人而异 2、配置环境变量 GOBIN : %GOROOT%\bin GOPATH : D:\MyGo 工作区间 GOROOT : D:\Program Files\Go GOJDK地址PATH: %GOBIN% ; %GOROOT%\bin ; …

Django模板的使用(详细版)

1、配置 在工程中创建模板目录templates&#xff08;这个名字可以变&#xff01;&#xff01;&#xff09; 在settings.py配置文件中修改TEMPLATES配置项的DIRS值 2、定义模板 在templates目录中新建一个模板文件&#xff0c;如index.html 3、模板渲染 Django提供了一个函数…

lua对接GPT4实现对话

演示效果&#xff1a; 准备材料&#xff1a; 1、FastWeb网站开发服务&#xff1a;fwlua.com 2、一台服务器 该示例使用开源项目&#xff1a;fastweb 实现。 代码比较简单&#xff0c;主要是两部分&#xff0c;一个lua代码和一个html页面&#xff0c;用来用户发起请求和后台…

【Bazel入门与精通】 rules之属性

https://bazel.build/extending/rules?hlzh-cn#attributes Attributes An attribute is a rule argument. Attributes can provide specific values to a target’s implementation, or they can refer to other targets, creating a graph of dependencies. Rule-specifi…

LeetCode 算法:矩阵置零c++

原题链接&#x1f517;&#xff1a;矩阵置零 难度&#xff1a;中等⭐️⭐️ 题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1…

13. UDP协议与RTP协议

UDP协议 UDP协议比较简单&#xff1a; UDP的长度是固定的&#xff0c;用总长度-UDP长度就是数据长度。 UDP是不保证他的有序性和可靠性的。对于音频和视频是这样是比较好的&#xff0c;因为这段丢了&#xff0c;我们可以从下一段在开始解码。 RTP RTP 协议概述 RTP&#x…

【讲解下Chrome DevTools,什么是Chrome DevTools?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

C语言 | Leetcode C语言题解之第143题重排链表

题目&#xff1a; 题解&#xff1a; struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow head;struct ListNode* fast head;while (fast->next ! NULL && fast->next->next ! NULL) {slow slow->next;fast fast->next-&g…