「iOS」3GShare总结

「iOS」3GShare项目总结

文章目录

share仿写的内容比之前几篇更多,相对来说也更难一些,所以总结一下我在仿写share所遇到的问题

注册登录界面

1.格式限制问题

对于注册界面的邮箱,邮箱是有一些固定的格式的,所以在此项目中需要判断限制输入的邮箱格式,在这里初次学习了谓词与正则表达式,具体内容移步谓词与正则表达式

这里给出相关代码与效果图

objc 复制代码
		NSString*regex = @"[A-Z0-9a-z]+@[A-Z0-9a-z]+\\.[A-Za-z]{2,}";
    NSPredicate*p = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    BOOL isValid = [p evaluateWithObject:_email.input.text];
    if(isValid){
        if(self.sendBackBlock)
        {
            self.sendBackBlock(_name.input.text, _pass.input.text);
        }
        NSUserDefaults*defaults = [NSUserDefaults standardUserDefaults];
        [defaults setObject:_name.input.text forKey:@"UserName"];
        [defaults setObject:_pass.input.text forKey:@"UserPassword"];
        [self dismissViewControllerAnimated:YES completion:nil];
    } else{
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"邮箱格式不正确" preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:nil]];
        [self presentViewController:alert animated:YES completion:nil];
        return;
    }

2.界面随键盘上下移

由上图可以看到输入的密码输入框比较靠下,如果弹出手机键盘后很容易就会挡到输入内容,所以我们需要监听键盘,在键盘弹出时让整个页面随键盘上移从而达到不遮挡的效果

代码与效果图如下

objc 复制代码
		self.offsetY = 0;
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];


-(void)keyboardWillShow:(NSNotification*)notify
{
    //获取键盘高度
    CGRect keyboardFrame = [notify.userInfo[UIKeyboardFrameEndUserInfoKey]CGRectValue];
    CGFloat keyboardH = keyboardFrame.size.height;
    //动画时长
    CGFloat duration = [notify.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
    //计算密码输入框底部
    CGFloat passBottom = CGRectGetMaxY(_pass.frame);
    CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
    //计算距离
    CGFloat space = screenH - passBottom;
    
    if (space < keyboardH) {
        self.offsetY = keyboardH - space + 20;
    } else {
        self.offsetY = 0;
    }
    
    // 执行平移动画
    [UIView animateWithDuration:duration animations:^{
        self.view.transform = CGAffineTransformMakeTranslation(0, -self.offsetY);
    }];
}

首页

点赞与传值

对于首页比较有问题的点就是假日页面与首页的点赞相互传值

我在这里是用两个数组永久保存每条作品的点赞数值与点亮状态,Cell 展示时读取数组;点击按钮改变状态、增减数字、回填数组,刷新对应 Cell 完成 UI 更新;配合 Block 传值完成详情页和首页数据双向同步。

点赞代码:

objc 复制代码
-(void)likeit:(UIButton*)sender
{
    NSInteger index = sender.tag;

    BOOL liked = [_likeStates[index] boolValue];
    NSInteger count = [_likeCounts[index] integerValue];
    
    if (liked) {
        count--;
        _likeStates[index] = @NO;
    } else {
        count++;
        _likeStates[index] = @YES;
    }
    sender.selected = [_likeStates[index] boolValue];

    _likeCounts[index] = @(count);

    NSIndexPath *targetIndex = [NSIndexPath indexPathForRow:0 inSection:index + 1];
    [self.tbView reloadRowsAtIndexPaths:@[targetIndex] withRowAnimation:UITableViewRowAnimationNone];
}

传值代码

objc 复制代码
//HomePage
__weak typeof(self) weakSelf = self;
        h.likeChangedBlock = ^(NSInteger likeCount, BOOL likeState) {
            weakSelf.likeCounts[idx] = @(likeCount);
            weakSelf.likeStates[idx] = @(likeState);

            NSIndexPath *reloadIndex = [NSIndexPath indexPathForRow:0 inSection:idx + 1];
            [weakSelf.tbView reloadRowsAtIndexPaths:@[reloadIndex] withRowAnimation:UITableViewRowAnimationNone];
        };

        [self.navigationController pushViewController:h animated:YES];

//详细页
- (void)likeAction:(UIButton *)sender {
    sender.selected = !sender.selected;
    if (sender.selected) {
        self.likeCount++;
    } else {
        self.likeCount--;
        if (self.likeCount < 0) self.likeCount = 0;
    }
    self.likeState = sender.selected;
    self.like_lab.text = [NSString stringWithFormat:@"%ld", (long)self.likeCount];

    if (self.likeChangedBlock) {
        self.likeChangedBlock(self.likeCount, self.likeState);
    }
}

搜索页

上传照片

上传照片记录照片数量与第一个照片传值回上传界面也是一个问题

我在这里用 NSMutableSet 存放被选中图片的数组下标数字,点击 cell:判断下标是否在集合内,存在就移除,不存在就加入,再用block传值传回上传界面

代码:

objc 复制代码
if (self.originSelectImgs.count > 0) {
        for (UIImage *oldImg in self.originSelectImgs) {
            NSInteger idx = [self.allPhotoArr indexOfObject:oldImg];
            if (idx != NSNotFound) {
                [self.selectedIndexSet addObject:@(idx)];
            }
        }
    }

NSMutableArray *selectImgArr = [NSMutableArray array];
    for (NSNumber *idxNum in self.selectedIndexSet) {
        NSInteger idx = idxNum.integerValue;
        if (idx < self.allPhotoArr.count) {
            [selectImgArr addObject:self.allPhotoArr[idx]];
        }
    }

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *idxNum = @(indexPath.item);
    if ([self.selectedIndexSet containsObject:idxNum]) {
        [self.selectedIndexSet removeObject:idxNum];
    } else {
        [self.selectedIndexSet addObject:idxNum];
    }
    [collectionView reloadItemsAtIndexPaths:@[indexPath]];
}

//传值
__weak typeof(self) weakSelf = self;
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        if (weakSelf.selectImageBlock) {
            weakSelf.selectImageBlock(selectImgArr);
        }
        [weakSelf.navigationController popViewControllerAnimated:YES];
    }]];

我的页

聊天室

模拟聊天室就是自定义cell的tableview,并记录状态是自己的消息还是对方的消息轮流发送

这里给出自定义cell的代码

objc 复制代码
#import "ChatMessageCell.h"
#import "MessageModel.h"
#import <Masonry/Masonry.h>

@interface ChatMessageCell ()
@property (nonatomic, strong) UILabel *timeLabel;
@property (nonatomic, strong) UIImageView *avatarImg;
@property (nonatomic, strong) UIView *bubbleView;
@property (nonatomic, strong) UILabel *contentLabel;
@end

@implementation ChatMessageCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        [self setupSubviews];
    }
    return self;
}

- (void)setupSubviews {

    // 时间
    self.timeLabel = [UILabel new];
    self.timeLabel.font = [UIFont systemFontOfSize:11];
    self.timeLabel.textColor = [UIColor lightGrayColor];
    self.timeLabel.textAlignment = NSTextAlignmentCenter;

    [self.contentView addSubview:self.timeLabel];

    [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.offset(8);
        make.centerX.equalTo(self.contentView);
        make.height.mas_equalTo(15);
    }];


    // 头像
    self.avatarImg = [UIImageView new];
    self.avatarImg.layer.cornerRadius = 20;
    self.avatarImg.clipsToBounds = YES;

    [self.contentView addSubview:self.avatarImg];

    // 气泡
    self.bubbleView = [UIView new];
    self.bubbleView.layer.cornerRadius = 8;
    self.bubbleView.layer.masksToBounds = YES;

    [self.contentView addSubview:self.bubbleView];

    // 内容
    self.contentLabel = [UILabel new];
    self.contentLabel.font = [UIFont systemFontOfSize:14];
    self.contentLabel.numberOfLines = 0;
    self.contentLabel.lineBreakMode =NSLineBreakByWordWrapping;

    [self.bubbleView addSubview:self.contentLabel];

    [self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.bubbleView).insets(UIEdgeInsetsMake(8, 10, 8, 10));
        make.width.lessThanOrEqualTo(@250);
    }];
}

- (void)fillCellWithModel:(MessageModel *)model {
    self.timeLabel.text = model.timeText;
    self.contentLabel.text = model.content;
    self.avatarImg.image = [UIImage imageNamed:model.avatarName];
    
    if (model.senderType == MessageSenderOther) {
        // 对方:左头像、灰色气泡
        self.bubbleView.backgroundColor = [UIColor colorWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1];
        self.contentLabel.textColor = [UIColor blackColor];
        [self.avatarImg mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.offset(10);
            make.top.equalTo(self.timeLabel.mas_bottom).offset(6);
            make.width.height.mas_equalTo(40);
        }];
        [self.bubbleView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(self.avatarImg.mas_right).offset(10);
            make.top.equalTo(self.avatarImg);
            make.width.lessThanOrEqualTo(self.contentView).multipliedBy(0.7);
            make.bottom.equalTo(self.contentView.mas_bottom).offset(-10);
        }];
    } else {
        // 自己:右头像、蓝色气泡
        self.bubbleView.backgroundColor = [UIColor systemBlueColor];
        self.contentLabel.textColor = [UIColor whiteColor];
        
        [self.avatarImg mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.right.offset(-10);
            make.top.equalTo(self.timeLabel.mas_bottom).offset(6);
            make.width.height.mas_equalTo(40);
        }];
        [self.bubbleView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(self.avatarImg.mas_left).offset(-10);
            make.top.equalTo(self.avatarImg);
            make.width.lessThanOrEqualTo(self.contentView).multipliedBy(0.7);
            make.bottom.equalTo(self.contentView.mas_bottom).offset(-10);
        }];
    }
}

@end
相关推荐
Lvan的前端笔记2 小时前
ios:区分 App Store / Ad Hoc / Development
ios
AI导出鸭3 小时前
如何让deepseek生成word文档 ?「AI 导出鸭」苹果版:从API流式解析到Pages级渲染,硬核攻克公式裂变与表格回流的终极方案。
人工智能·chatgpt·word·cocoa·ai导出鸭
Lvan的前端笔记4 小时前
ios:证书配置
ios
FeliksLv6 小时前
从 +load 到 Swift Macros:自动注册的演进与实践
ios·objective-c·swift
嵌入式小周7 小时前
Genymotion 安卓模拟器在 Intel 芯片 Mac 上的运行(附带下载方式)
android·macos
Lvan的前端笔记7 小时前
ios:GitHub Actions云端Xcode26打包上架TestFlight
macos·github·xcode
寒水馨8 小时前
macOS下载、安装godot-4.7.1-stable(附安装包Godot_v4.7.1-stable_macos.universal.zip)
macos·3d·游戏引擎·godot·跨平台·游戏开发·2d
2501_9159184118 小时前
深入对比iOS开发中常用性能监控工具的底层原理与优缺点分析
android·ios·小程序·https·uni-app·iphone·webview
七牛云行业应用1 天前
Ollama 本地部署 DeepSeek 完全指南:macOS / Windows / Linux 三端安装 + GPU 配置 + API 调用
linux·windows·macos