修改了登录im的逻辑

This commit is contained in:
fengshuo
2024-02-29 23:49:12 +08:00
parent 70e6ca8204
commit 26d586290c
26 changed files with 1536 additions and 55 deletions

View File

@@ -8,6 +8,7 @@
import UIKit
import DeviceKit
import NSObject_Rx
import NIMSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
@@ -18,7 +19,9 @@ var window: UIWindow?
self.window = UIWindow.init(frame: UIScreen.main.bounds)
self.window?.backgroundColor = UIColor.white
self.window?.rootViewController = BaseNavigationViewController(rootViewController:AuthLaunchVC())
loadNIMSDK()
loginStateListener()
return true
}
@@ -34,13 +37,36 @@ var window: UIWindow?
if let uid = LoginTokenConfig.config.getAccountInfo()?.uid {
UserViewModel.userVM.getUserInfo(uid: uid)
}
if NIMSDK.shared().loginManager.isLogined() == false {
if let uid = LoginTokenConfig.config.getAccountInfo()?.uid, let token = LoginTokenConfig.config.getAccountInfo()?.netEaseToken {
NIMSDK.shared().loginManager.login("\(uid)", token: token) { error in
print("aaa")
}
} else {
///
self.window?.rootViewController = BaseNavigationViewController(rootViewController:AuthLaunchVC())
}
}
} else {
///
self.window?.rootViewController = BaseNavigationViewController(rootViewController:AuthLaunchVC())
}
}).disposed(by: rx.disposeBag)
UserViewModel.userVM.userInfo.subscribe(onNext: { result in
if result.nick?.count ?? 0 <= 0 || result.avatar?.count ?? 0 <= 0 {
let fillVC = AuthFillDataVC()
fillVC.modalPresentationStyle = .fullScreen
YMRequestX.topViewController()?.navigationController?.present(fillVC, animated: true)
}
}).disposed(by: rx.disposeBag)
}
private func loadNIMSDK() {
let opt = NIMSDKOption(appKey: AppKeys.nimAppid)
opt.apnsCername = "yinmeng_anps"
NIMSDK.shared().register(with: opt)
}
}

View File

@@ -2,7 +2,7 @@
// YMNetworkAPI.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/24.
// Created by Mang on 2024/2/24.
//
import Foundation
@@ -37,7 +37,7 @@ class YMNetworkHelper: NSObject {
func requestSend(type:HTTPMethod,path:String,params:Dictionary<String, Any>, succeed:SessionCallSucceed?,fail:SessionCallFail?) -> Void {
getHttpRequestHeaders()
requestSend(type: type,host: "https://api.ymlive.fun/", path: path, params: params, encoding: URLEncoding.queryString, header: headersSet, succeed: succeed, fail: fail)
requestSend(type: type,host: AppKeys.api, path: path, params: params, encoding: URLEncoding.queryString, header: headersSet, succeed: succeed, fail: fail)
}
func requestSend(type:HTTPMethod,
@@ -74,50 +74,50 @@ class YMNetworkHelper: NSObject {
func analyzeThe(response1:AFDataResponse<Any>,
succeed2:SessionCallSucceed?,
fail3: SessionCallFail?,uuid4:String) -> Void {
let maiUrlSss = response1.request?.url?.absoluteString ?? "unkown"
let UrlSss = response1.request?.url?.absoluteString ?? "unkown"
switch response1.result {
case .success:
let maiResponNk :Dictionary = response1.value as? Dictionary<String, Any> ?? Dictionary.init()
let maiResultMo = maiResponNk
if maiResultMo.keys.contains("code") {
let maicodeNum :Int = maiResultMo["code"] as? Int ?? 0
if maicodeNum == 200 {
if maiResultMo.keys.contains("data") {
let maiDDD = maiResultMo["data"] as Any
succeed2?(maiDDD)
let ResponNk :Dictionary = response1.value as? Dictionary<String, Any> ?? Dictionary.init()
let ResultMo = ResponNk
if ResultMo.keys.contains("code") {
let codeNum :Int = ResultMo["code"] as? Int ?? 0
if codeNum == 200 {
if ResultMo.keys.contains("data") {
let DDD = ResultMo["data"] as Any
succeed2?(DDD)
}else{
succeed2?(Dictionary<String, Any>.init())
}
}else{
if maicodeNum == 401 && maiUrlSss.contains("auth-center/sso/logout") == false {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "MAISessionTickValid"), object: nil)
if codeNum == 401 && UrlSss.contains("auth-center/sso/logout") == false {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SessionTickValid"), object: nil)
sessionNetMana.cancelAllRequests()
}
var messageIn = response1.error.debugDescription
if maiResultMo.keys.contains("message") { messageIn = maiResultMo["message"] as? String ?? "" }
fail3?(maicodeNum,messageIn)
if ResultMo.keys.contains("message") { messageIn = ResultMo["message"] as? String ?? "" }
fail3?(codeNum,messageIn)
}
} else if maiResultMo.keys.contains("errno") {
let maiCodeNum :Int = maiResultMo["errno"] as? Int ?? 0
if maiCodeNum == 0 {
if maiResultMo.keys.contains("data") {
let dataSc = maiResultMo["data"] as Any
} else if ResultMo.keys.contains("errno") {
let CodeNum :Int = ResultMo["errno"] as? Int ?? 0
if CodeNum == 0 {
if ResultMo.keys.contains("data") {
let dataSc = ResultMo["data"] as Any
succeed2?(dataSc)
}else{
succeed2?(Dictionary<String, Any>.init())
}
}else{
var majmessageStr = response1.error.debugDescription
if maiResultMo.keys.contains("errmsg") { majmessageStr = maiResultMo["errmsg"] as? String ?? ""}
fail3?(maiCodeNum,majmessageStr)
if ResultMo.keys.contains("errmsg") { majmessageStr = ResultMo["errmsg"] as? String ?? ""}
fail3?(CodeNum,majmessageStr)
}
} else {
fail3?(10000,"请求失败")
}
case let .failure(error):
var maiErrorMssg = response1.error?.errorDescription ?? ""
var maicodeNum = response1.error?.responseCode ?? 0
fail3?(maicodeNum,maiErrorMssg)
var ErrorMssg = response1.error?.errorDescription ?? ""
var codeNum = response1.error?.responseCode ?? 0
fail3?(codeNum,ErrorMssg)
}
}

View File

@@ -0,0 +1,17 @@
//
// AppKeys.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import Foundation
enum AppKeys {
#if DEBUG
static let nimAppid = "5d5a833a2d0ff1304a5d8bed53d2af5b"
static let api = "http://beta.api.ymlive.fun/"
#else
static let nimAppid = "5e76ec47632d86c30ce18eabfa332b6a"
static let api = "https://api.ymlive.fun/"
#endif
}

View File

@@ -9,5 +9,6 @@ import Foundation
enum H5Utils:String {
case privacy = "modules/rule/privacy-wap.html"
case user = "modules/rule/protocol.html"
case logoff = "modules/logout/index.html"
}

View File

@@ -31,6 +31,4 @@ let TabHeight = (49)
let DesKey = "1ea53d260ecf11e7b56e00163e046a26"
let API_URL = "http://beta.api.ymlive.fun"
let H5_URL = "http://beta.h5.ymlive.fun"

View File

@@ -0,0 +1,161 @@
//
// UIView+.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import UIKit
extension UIView {
/// x
public var x : CGFloat {
get {
return self.frame.origin.x
}
set (x) {
var frame = self.frame
frame.origin.x = x
self.frame = frame
}
}
/// y
public var y : CGFloat {
get {
return self.frame.origin.y
}
set (y) {
var frame = self.frame
frame.origin.y = y
self.frame = frame
}
}
/// maxX
public var maxX : CGFloat {
get {
return self.frame.maxX
}
set(maxX) {
self.frame.origin.x = maxX - self.frame.size.width
}
}
/// maxY
public var maxY : CGFloat {
get {
return self.frame.maxY
}
set(maxY) {
self.frame.origin.y = maxY - self.frame.size.height
}
}
/// width
public var width : CGFloat {
get {
return self.frame.size.width
}
set (width) {
var frame = self.frame
frame.size.width = width
self.frame = frame
}
}
/// height
public var height : CGFloat {
get {
return self.frame.size.height
}
set (height) {
var frame = self.frame
frame.size.height = height
self.frame = frame
}
}
/// centerX
public var centerX : CGFloat {
get {
return self.center.x
}
set (centerX) {
var center = self.center
center.x = centerX
self.center = center
}
}
/// centerY
public var centerY : CGFloat {
get {
return self.center.y
}
set (centerY) {
var center = self.center
center.y = centerY
self.center = center
}
}
/// size
public var size : CGSize {
get {
return self.frame.size
}
set (size) {
var newSize = self.frame.size
newSize = CGSize(width: size.width, height: size.height)
self.frame.size = newSize
}
}
/// origin
public var origin : CGPoint {
get {
return self.frame.origin
}
set (origin) {
var newOrigin = self.frame.origin
newOrigin = CGPoint(x: origin.x, y: origin.y)
self.frame.origin = newOrigin
}
}
/// borderWidth
public var borderWidth: CGFloat {
get {
return self.layer.borderWidth
}
set (borderWidth){
self.layer.borderWidth = borderWidth
guard self.layer.masksToBounds else {
return
}
self.layer.masksToBounds = true
}
}
}

View File

@@ -16,6 +16,7 @@ class AuthFillDataVC: BaseViewController, HiddenNavigationBarProtocol {
}
private func loadSubViews() {
randomNick()
view.addSubview(backImgView)
view.addSubview(backBtn)
view.addSubview(titleLb)
@@ -144,6 +145,16 @@ class AuthFillDataVC: BaseViewController, HiddenNavigationBarProtocol {
return button
}()
fileprivate func randomNick() {
RequestGet(path: "random/nick/get", parma: [:]) { text in
if let text = text as? String {
self.nickTextFiled.text = text
}
} fail: { code, msg in
}
}
@objc func femaleBtnAction() {
self.femaleBtn.isSelected = true
self.maleBtn.isSelected = false
@@ -157,14 +168,36 @@ class AuthFillDataVC: BaseViewController, HiddenNavigationBarProtocol {
@objc func backBtnAction() {
self.navigationController?.popViewController(animated: true)
self.dismiss(animated: true, completion: nil)
AuthViewModel.authVM.logout()
}
@objc func nickTextFiledDidChange(_ textField: UITextField) {
if let text = textField.text {
if text.count > 15 {
textField.text = text.substring(start: 0, 15)
}
}
}
@objc func confirmBtnAction() {
if maleBtn.isSelected == true || femaleBtn.isSelected == true {
if let nick = nickTextFiled.text, nick.count > 0 {
let gender = self.maleBtn.isSelected ? "1" : "2"
let params:[String: Any] = ["avatar":"https://image.ymlive.fun/default_avatar.png", "nick": nick, "gender":gender, "uid": AuthManager.userUid, "ticket":AuthManager.ticket]
RequestPost(path: "user/v2/update", parma: params) { data in
HUDTool.show(with: "更新成功")
self.dismiss(animated: true, completion: nil)
} fail: { code, message in
HUDTool.show(with: message)
}
} else {
HUDTool.show(with: "请输入昵称")
}
} else {
HUDTool.show(with: "请选择性别")
}
}
}

View File

@@ -281,7 +281,7 @@ class AuthLaunchVC: BaseViewController, HiddenNavigationBarProtocol {
}
@objc func userProtocolBtnAction() {
let web = WebViewController(url: "yinmeng/\(H5Utils.privacy.rawValue)")
let web = WebViewController(url: "yinmeng/\(H5Utils.user.rawValue)")
self.navigationController?.pushViewController(web, animated: true)
}

View File

@@ -22,6 +22,7 @@ class AuthManager: NSObject {
}
}
class LoginTokenConfig: NSObject {
public static let config = LoginTokenConfig.init()
var tokenInfo: UserTokenObject?

View File

@@ -7,6 +7,7 @@
import Foundation
import RxSwift
import NIMSDK
class AuthViewModel: NSObject {
static let authVM = AuthViewModel.init()
let data = PublishSubject<Bool>()
@@ -22,6 +23,24 @@ class AuthViewModel: NSObject {
}
}
func logout() {
if NIMSDK.shared().loginManager.isLogined() {
NIMSDK.shared().loginManager.logout()
}
let token = LoginTokenConfig.config.getAccountInfo()?.access_token
LoginTokenConfig.config.removeTicketFromLoaction()
LoginTokenConfig.config.removeTicketFromLoaction()
if let token = token {
let params = ["auaccess_token": token]
RequestPost(path: "acc/logout", parma: params) { data in
print("你好")
} fail: { code, msg in
print("de")
}
}
self.loginSuccess.onNext(false)
}
///
func getSmsCode(phone:String, type:Int) {
if let phoneDes = phone.encrypt() {
@@ -106,14 +125,11 @@ class AuthViewModel: NSObject {
if let dic = data as? [String: Any], let tickets = dic["tickets"] as? [[String: Any]], let ticket1 = tickets[safe: 0], let ticket = ticket1["ticket"] as? String{
LoginTokenConfig.config.saveTicketToLoaction(ticket: ticket)
self.loginSuccess.onNext(true)
self.loginSuccess.onCompleted()
} else {
self.loginSuccess.onNext(false)
self.loginSuccess.onCompleted()
}
} fail: { code, message in
self.loginSuccess.onNext(false)
self.loginSuccess.onCompleted()
}
}

View File

@@ -6,13 +6,136 @@
//
import UIKit
import NIMSDK
class ChatListVC: BaseViewController {
var list:NSMutableArray?
deinit {
NIMSDK.shared().loginManager.remove(self)
NIMSDK.shared().conversationManager.remove(self)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
NIMSDK.shared().conversationManager.add(self)
NIMSDK.shared().loginManager.add(self)
getList()
}
private lazy var tableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .plain)
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
tableView.separatorStyle = .none
tableView.backgroundColor = .clear
if #available(iOS 11.0, *) {
tableView.contentInsetAdjustmentBehavior = .never
}
tableView.register(cellType: ChatListCell.self)
return tableView
}()
}
extension ChatListVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatListCell.self)
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list?.count ?? 0
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 64
}
}
extension ChatListVC: NIMConversationManagerDelegate, NIMLoginManagerDelegate {
func onLogin(_ step: NIMLoginStep) {
if (step == .syncOK) {
getList()
}
}
func didLoadAllRecentSessionCompletion() {
getList()
}
func didAdd(_ recentSession: NIMRecentSession, totalUnreadCount: Int) {
var isInList = false
for index in 0..<(list?.count ?? 0) {
let recent = list?[index] as? NIMRecentSession
if recent?.session?.sessionId == recentSession.session?.sessionId{
isInList = true
list?.replaceObject(at: index, with: recentSession)
break
}
}
if isInList == false {
list?.add(recentSession)
}
mai_sortMessages()
updateItemBadge()
}
func didUpdate(_ recentSession: NIMRecentSession, totalUnreadCount: Int) {
var isInList = false
for index in 0..<(list?.count ?? 0) {
let session = list?[index] as? NIMRecentSession
if session?.session?.sessionId == recentSession.session?.sessionId{
isInList = true
list?.replaceObject(at: index, with: recentSession)
break
}
}
if isInList == false {
list?.add(recentSession)
}
mai_sortMessages()
updateItemBadge()
}
func didRemove(_ recentSession: NIMRecentSession, totalUnreadCount: Int) {
let arr = NSArray.init(object: recentSession.session as Any)
NIMSDK.shared().conversationManager.deleteRemoteSessions(arr as! [NIMSession], completion: nil)
tableView.reloadData()
}
}
extension ChatListVC {
fileprivate func getList() {
if let array = NIMSDK.shared().conversationManager.allRecentSessions() {
list = NSMutableArray.init(array: array)
mai_sortMessages()
}
}
fileprivate func mai_sortMessages() -> Void {
var arr = list?.sortedArray(options: NSSortOptions.stable, usingComparator: { obj1, obj2 in
let item1 = obj1 as? NIMRecentSession
let item2 = obj2 as? NIMRecentSession
let time1 = (item1?.lastMessage?.timestamp ?? 0) as Double
let time2 = (item2?.lastMessage?.timestamp ?? 0) as Double
if time1 < time2{
return .orderedDescending
}
return .orderedAscending
})
if let array = arr {
list = NSMutableArray(array: array)
}
tableView.reloadData()
}
private func updateItemBadge() {
let unreadCount = NIMSDK.shared().conversationManager.allUnreadCount()
self.tabBarItem.badgeValue = "\(unreadCount)"
}
}

View File

@@ -9,25 +9,39 @@ import UIKit
import NIMSDK
class ChatVC: BaseViewController {
// /
private var isBecome: Bool = false
///
private var isSended: Bool = true
///
private let ToolBarLastH: CGFloat = 52
public init(session: NIMSession) {
vm = ChatViewModel(session: session)
super.init(nibName: nil, bundle: nil)
// vm.delegate = self
// NIMSDK.shared().mediaManager.add(self)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var vm:ChatViewModel
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .orange
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = ThemeColor(hexStr: "#F6F6F6")
let height = ScreenHeight - (ToolBarLastH + SafeAraeBottomHeight + NavHeight)
chatTableView.frame = CGRect(x: 0, y: 0, width: ScreenWidth, height: height)
view.addSubview(chatTableView)
view.addSubview(keyboardView)
}
///cell
private func registerChatCell() {
chatTableView.register(cellType: ChatTextCell.self)
}
private lazy var chatTableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .plain)
@@ -42,20 +56,57 @@ class ChatVC: BaseViewController {
return tableView
}()
private lazy var keyboardView: ChatKeyboardView = {
let toolBarY = ScreenHeight - NavHeight - ToolBarLastH - SafeAraeBottomHeight
let view = ChatKeyboardView(frame: CGRect(x: 0, y: toolBarY, width: ScreenWidth, height: ToolBarLastH))
view.delegate = self
return view
}()
}
extension ChatVC: UITableViewDelegate, UITableViewDataSource {
// MARK: - ChatKeyboardViewDelegate
extension ChatVC: ChatKeyboardViewDelegate {
func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String) {
///
vm.sendTextMessage(text: content) { error in
}
}
func keyboard(_ keyboard: ChatKeyboardView, DidBecome isBecome: Bool) {
self.isSended = true
self.isBecome = isBecome
}
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType) {
//TODO:
}
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat) {
}
}
extension ChatVC: UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vm.messageObjects.count
}
public func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = vm.messageObjects[safe: indexPath.row]
if model?.type == .text {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatTextCell.self)
cell.model = model
}
return UITableViewCell()
}
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
public func tableView(_ tableView: UITableView,
@@ -63,4 +114,22 @@ extension ChatVC: UITableViewDelegate, UITableViewDataSource {
let m = vm.messageObjects[safe:indexPath.row]
return CGFloat(m?.height ?? 0)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if isSended {
isSended = false
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if isSended {
return
}
if chatTableView.y <= 0 && isBecome {
DispatchQueue.main.async {
NotificationCenter.default.post(name: .kChatTextKeyboardNeedHide, object: nil)
}
}
}
}

View File

@@ -0,0 +1,153 @@
//
// ChatGrowingTextView.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import UIKit
class ChatGrowingTextView: UITextView {
///
fileprivate let kEdgeInset: CGFloat = 12
///
fileprivate let kDefultSize: CGFloat = 15.0
// MARK: - var lazy
/// 3
fileprivate var maxTextViewHeight: CGFloat = 80
var placeholder: String? = "" {
didSet {
self.placeholderLabel.text = placeholder
}
}
var placeholderColor: UIColor? = .black {
didSet {
self.placeholderLabel.textColor = placeholderColor
}
}
var maxNumberOfLines: Int = 3 {
didSet {
let numberOfLines = CGFloat(maxNumberOfLines)
maxTextViewHeight = CGFloat(ceilf(Float(self.font!.lineHeight * numberOfLines + self.textContainerInset.top + self.textContainerInset.bottom))) - kEdgeInset
}
}
///
var didTextChangedHeightClosure : ((CGFloat)->Void)?
///
fileprivate lazy var placeholderLabel: UILabel = {
let frame = CGRect(x: 5, y: 7, width: ScreenWidth - 10, height: 21)
let label = UILabel(frame: frame)
label.numberOfLines = 1
label.text = "请输入你要发送的消息"
label.textColor = ThemeColor(hexStr: "#F6F6F6")
label.font = UIFont.systemFont(ofSize: self.kDefultSize)
return label
}()
// MARK: - life cycle
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
setup()
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate func setup() {
backgroundColor = .white
self.isScrollEnabled = false
self.scrollsToTop = false
//self.contentInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
self.showsHorizontalScrollIndicator = false
self.enablesReturnKeyAutomatically = true
self.font = UIFont.systemFont(ofSize: kDefultSize)
self.returnKeyType = .send
self.layer.cornerRadius = 4
self.layer.borderWidth = 1
self.layer.borderColor = ThemeColor(hexStr: "#2C363E").cgColor
self.layer.masksToBounds = true
//
addSubview(self.placeholderLabel)
// register
registerChangeNotification()
}
fileprivate func registerChangeNotification() {
//
NotificationCenter.default.addObserver(self,
selector: #selector(textDidChanged),
name: UITextView.textDidChangeNotification,
object: self)
self.addObserver(self, forKeyPath: "attributedText", options: .new, context: nil)
}
// MARK: - KVO
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "attributedText" {
textDidChanged()
}else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
deinit {
NotificationCenter.default.removeObserver(self)
self.removeObserver(self, forKeyPath: "attributedText")
}
}
// MARK: - Action
extension ChatGrowingTextView {
@objc func textDidChanged() {
placeholderLabel.isHidden = self.hasText
//
let constrainSize = CGSize(width: self.frame.size.width, height: CGFloat(MAXFLOAT))
var size = self.sizeThatFits(constrainSize)
if size.height >= maxTextViewHeight {
self.isScrollEnabled = true
size.height = maxTextViewHeight
}else {
self.isScrollEnabled = false
if (didTextChangedHeightClosure != nil && !self.isScrollEnabled) {
didTextChangedHeightClosure?(size.height)
}
}
let nowFrame = self.frame
frame.size.height = size.height
self.frame = nowFrame
self.layoutIfNeeded()
sendChangedNoti()
}
func sendChangedNoti() {
NotificationCenter.default.post(name: .kChatTextKeyboardChanged, object: self.text, userInfo: nil)
}
}

View File

@@ -0,0 +1,29 @@
//
// ChatKeyboard+.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import Foundation
// MARK: - NSNotificationName
public extension NSNotification.Name {
///
static let kChatTextKeyboardNeedHide = Notification.Name("kChatTextKeyboardNeedHide")
///
static let kChatTextKeyboardChanged = Notification.Name("kChatTextKeyboardChanged")
}
protocol OptionalType {
associatedtype Wrapped
var value: Wrapped? { get }
}
extension Optional: OptionalType {
var value: Wrapped? {
return self
}
}

View File

@@ -0,0 +1,371 @@
//
// ChatKeyboardView.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import UIKit
protocol ChatKeyboardViewDelegate: NSObjectProtocol {
///
func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String)
/// /
func keyboard(_ keyboard: ChatKeyboardView, DidBecome isBecome: Bool)
/// y
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat)
///
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType)
}
extension ChatKeyboardViewDelegate {
func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String) {}
func keyboard(_ keyboard: ChatKeyboardView, DidBecome isBecome: Bool) {}
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat) {}
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType) {}
}
class ChatKeyboardView: UIView {
private let kSpace: CGFloat = 8.0
private let kViewWH: CGFloat = 36.0
private let kLineHeight: CGFloat = 0.75
// MARK: - var lazy
weak var delegate: ChatKeyboardViewDelegate?
fileprivate var toolBarHeight: CGFloat = 52.0
fileprivate var lastTextHeight: CGFloat = 34.0
fileprivate var keyboardHeight: CGFloat = 0.0
///
fileprivate var contentHeight: CGFloat = 0.0
fileprivate var isShowMore = false
///
fileprivate var isShowKeyboard = false
///
fileprivate lazy var moreButton : UIButton = {
let button = UIButton(type: .custom)
let x: CGFloat = ScreenWidth - self.kViewWH - self.kSpace
button.frame = CGRect(x: x, y: self.kSpace, width: self.kViewWH, height: self.kViewWH)
button.setImage(UIImage(named: "chat_more"), for: .normal)
button.setImage(UIImage(named: "chat_more"), for: .highlighted)
button.addTarget(self, action: #selector(moreDidAction(_:)), for: .touchUpInside)
return button
}()
///
fileprivate lazy var chatTextView: ChatGrowingTextView = {
let w: CGFloat = ScreenWidth - self.kViewWH * 2 - self.kSpace * 3 - self.kSpace
let textView = ChatGrowingTextView(frame: CGRect(x: self.kSpace, y: self.kSpace, width: w, height: self.kViewWH))
textView.placeholder = "请输入..."
textView.textColor = ThemeColor(hexStr: "#000000")
textView.maxNumberOfLines = 5
textView.delegate = self
textView.didTextChangedHeightClosure = { [weak self] height in
self?.changeKeyboardHeight(height: height)
}
return textView
}()
fileprivate lazy var topLineView: UIView = {
let lineView1 = UIView(frame: CGRect(x: 0, y: 0, width: ScreenWidth, height: kLineHeight))
lineView1.backgroundColor = ThemeColor(hexStr: "#E5E5E5")
return lineView1
}()
fileprivate lazy var bottomLineView: UIView = {
let lineView2 = UIView(frame: CGRect(x: 0, y: self.toolBarHeight - kLineHeight, width: ScreenWidth, height: kLineHeight))
lineView2.backgroundColor = ThemeColor(hexStr: "#E5E5E5")
return lineView2
}()
fileprivate lazy var toolBarView: UIView = {
let view = UIView(frame: CGRect(x: 0, y: 0, width: ScreenWidth, height: self.toolBarHeight))
view.backgroundColor = ThemeColor(hexStr: "#F7F7F7")
return view
}()
///
fileprivate lazy var contentView: UIView = {
let y = self.toolBarView.maxY
let view = UIView(frame: CGRect(x: 0, y: y, width: ScreenWidth, height: self.contentHeight))
view.backgroundColor = ThemeColor(hexStr: "#F8F8F8")
return view
}()
///
fileprivate lazy var moreMenuView: ChatMoreMenuView = {
let view = ChatMoreMenuView(frame: self.contentView.bounds)
view.isHidden = true
view.delegate = self
return view
}()
// MARK: - life cycle
override init(frame: CGRect) {
super.init(frame: frame)
setupKeyboardView()
registerNotification()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupKeyboardView()
registerNotification()
}
func setupKeyboardView() {
self.backgroundColor = ThemeColor(hexStr: "#F7F7F7")
self.isUserInteractionEnabled = true
addSubview(toolBarView)
toolBarView.addSubview(moreButton)
toolBarView.addSubview(chatTextView)
toolBarView.addSubview(topLineView)
toolBarView.addSubview(bottomLineView)
addSubview(contentView)
contentView.addSubview(moreMenuView)
}
// MARK: -
private func registerNotification() {
//
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)),
name:UIResponder.keyboardWillShowNotification,object: nil)
//
NotificationCenter.default.addObserver(self,selector: #selector(keyboardWillHide(_:)),
name: UIResponder.keyboardWillHideNotification, object: nil)
//
NotificationCenter.default.addObserver(self,selector: #selector(keyboardNeedHide),
name: .kChatTextKeyboardNeedHide, object: nil)
// KVOy
addObserver(self, forKeyPath: "frame", options: [.new, .old], context: nil)
}
// MARK: - KVO
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "frame" && ((object as? UIView) != nil) {
if let changeObject = change.value {
if let newFrame = changeObject[.newKey] as? CGRect {
delegate?.keyboard(self, DidObserver: newFrame.origin.y)
print("y值发生改变\(newFrame.origin.y)")
}
}
}else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
deinit {
self.removeObserver(self, forKeyPath: "frame")
}
}
// MARK: - ChatMoreMenuViewDelegate
extension ChatKeyboardView: ChatMoreMenuViewDelegate {
func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType) {
delegate?.keyboard(self, DidMoreMenu: type)
}
}
// MARK: - UITextViewDelegate
extension ChatKeyboardView: UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
// &
if (text == "\n") {
if (isShowKeyboard) {
isShowKeyboard = true
}
sendChatMessage()
return false
}
return true
}
///
private func sendChatMessage() {
delegate?.keyboard(self, DidFinish: self.chatTextView.text ?? "")
changeKeyboardHeight(height: lastTextHeight)
chatTextView.text = ""
chatTextView.attributedText = NSAttributedString(string: "")
}
}
// MARK: - KeyBoard Manager
extension ChatKeyboardView {
///
@objc func keyboardWillShow(_ noti: NSNotification) {
guard let userInfo = noti.userInfo else {
return
}
contentHeight = 0
delegate?.keyboard(self, DidBecome: true)
let duration = userInfo["UIKeyboardAnimationDurationUserInfoKey"] as! Double
let endFrame = (userInfo["UIKeyboardFrameEndUserInfoKey"] as! NSValue).cgRectValue
let y = endFrame.origin.y
//
keyboardHeight = endFrame.height
//
isShowKeyboard = true
let option = userInfo["UIKeyboardAnimationCurveUserInfoKey"] as! Int
var changedY = y - self.toolBarHeight - NavHeight - contentHeight
if (isShowMore) { //
isShowMore = false
self.moreMenuView.isHidden = true
self.moreMenuView.hidePageController = true
changedY = y - self.toolBarHeight - NavHeight
}
UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: UIView.AnimationOptions.RawValue(option)), animations: {
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: self.toolBarHeight + self.contentHeight)
}, completion: nil)
}
///
@objc func keyboardWillHide(_ noti: NSNotification) {
guard let userInfo = noti.userInfo else {
return
}
delegate?.keyboard(self, DidBecome: false)
let duration = userInfo["UIKeyboardAnimationDurationUserInfoKey"] as! Double
let endFrame = (userInfo["UIKeyboardFrameEndUserInfoKey"] as! NSValue).cgRectValue
//let y = endFrame.origin.y
//
keyboardHeight = endFrame.height
//
isShowKeyboard = false
let option = userInfo["UIKeyboardAnimationCurveUserInfoKey"] as! Int
let changedY = ScreenHeight - NavHeight - self.toolBarHeight - SafeAraeBottomHeight - self.contentHeight
UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: UIView.AnimationOptions.RawValue(option)), animations: {
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: self.toolBarHeight + self.contentHeight)
}, completion: nil)
}
@objc func keyboardNeedHide(_ noti: NSNotification) {
chatTextView.resignFirstResponder()
moreMenuView.hidePageController = true
contentHeight = 0.0
restToolbarContentHeight(true)
delegate?.keyboard(self, DidBecome: false)
}
}
// MARK: - Action
extension ChatKeyboardView {
///
@objc func moreDidAction(_ button: UIButton) {
//
if isShowMore {
return
}
isShowMore = true
contentHeight = 250
contentView.isHidden = false
moreMenuView.isHidden = false
chatTextView.resignFirstResponder()
restToolbarContentHeight()
moreMenuView.reloadData()
delegate?.keyboard(self, DidBecome: true)
}
///
func restToolbarContentHeight(_ isRest: Bool = false) {
var changedY = ScreenHeight - self.toolBarHeight - NavHeight - contentHeight
if (isRest) {
if (isShowMore) {
isShowMore = false
}
changedY = ScreenHeight - self.toolBarHeight - NavHeight - contentHeight - SafeAraeBottomHeight
}
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut, animations: {
self.contentView.frame = CGRect(x: 0, y: self.toolBarView.maxY, width: ScreenWidth, height: self.contentHeight)
self.moreMenuView.frame = self.contentView.bounds
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: self.toolBarHeight + self.contentHeight)
}, completion: nil)
self.layoutIfNeeded()
}
}
// MARK: -
extension ChatKeyboardView {
func changeKeyboardHeight(_ isClear: Bool = false, height: CGFloat) {
let textHeight = height
toolBarHeight = textHeight + kSpace * 2
toolBarView.frame = CGRect(x: toolBarView.x, y: 0, width: toolBarView.width, height: toolBarHeight)
let spaceY = toolBarView.height - kSpace - kViewWH
chatTextView.frame = CGRect(x: chatTextView.x, y: chatTextView.x, width: chatTextView.width, height: textHeight)
moreButton.frame = CGRect(x: moreButton.x, y: spaceY, width: moreButton.width, height: moreButton.height)
contentView.frame = CGRect(x: contentView.x, y: toolBarView.maxY, width: contentView.width, height: contentHeight)
topLineView.frame = CGRect(x: 0, y: 0, width: ScreenWidth, height: kLineHeight)
bottomLineView.frame = CGRect(x: 0, y: toolBarView.height - kLineHeight, width: ScreenWidth, height: kLineHeight)
if (isShowKeyboard) {
if (isShowMore) {
isShowMore = false
}
let changedY = ScreenHeight - keyboardHeight - toolBarHeight - NavHeight
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: toolBarView.height + contentView.height)
}else {
let changedY = ScreenHeight - NavHeight - (toolBarView.height + contentView.height)
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: toolBarView.height + contentView.height)
}
self.setNeedsLayout()
print("self y === \(self.frame.origin.y)")
}
}

View File

@@ -0,0 +1,67 @@
//
// ChatMoreMenuCell.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import UIKit
import Reusable
class ChatMoreMenuCell: UICollectionViewCell, Reusable {
// MARK: - lazy var
var model: ChatMoreMnueConfig? {
didSet {
guard model != nil else {
return
}
self.imageView.image = UIImage(named: model!.image!)
self.titleLabel.text = model?.title ?? ""
}
}
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.textColor = .white
label.font = UIFont.systemFont(ofSize: 14)
return label
}()
private lazy var imageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
// MARK: - life cycle
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(imageView)
contentView.addSubview(titleLabel)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
imageView.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview().offset(-10)
make.width.height.equalTo(36)
}
titleLabel.snp.makeConstraints { (make) in
make.left.right.equalToSuperview()
make.top.equalTo(imageView.snp.bottom)
make.height.equalTo(21)
}
}
}

View File

@@ -0,0 +1,262 @@
//
// ChatMoreMenuView.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import UIKit
enum ChatMoreMenuType: Int {
case album = 1001
case camera = 1002
}
///
fileprivate let kRowNumber = 2
///
fileprivate let kColumnNumber = 4
fileprivate let kMoreMenuCellNumberOfOnePage = kRowNumber * kColumnNumber
protocol ChatMoreMenuViewDelegate {
///
func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType)
}
extension ChatMoreMenuViewDelegate {
func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType) {}
}
class ChatMoreMenuView: UIView {
// MARK: - lazy var
var delegate: ChatMoreMenuViewDelegate?
///
var hidePageController: Bool = false {
didSet {
self.pageControl.alpha = self.hidePageController ? 0.0 : 1.0
UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut, animations: {
self.pageControl.isHidden = self.hidePageController
}, completion: nil)
self.collectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .centeredHorizontally, animated: false)
}
}
var pageIndicatorTintColor: UIColor? {
didSet {
guard pageIndicatorTintColor != nil else {
return
}
pageControl.pageIndicatorTintColor = pageIndicatorTintColor
}
}
var currentPageIndicatorTintColor: UIColor? {
didSet {
guard currentPageIndicatorTintColor != nil else {
return
}
pageControl.currentPageIndicatorTintColor = currentPageIndicatorTintColor
}
}
lazy var dataSource: [ChatMoreMnueConfig] = {
let configs = [
ChatMoreMnueConfig(title: "图片", image: "ic_more_album", type: .album),
ChatMoreMnueConfig(title: "拍照", image: "ic_more_camera", type: .camera)
]
return configs
}()
lazy var collectionView: UICollectionView = {
let layout = ChatKeyboardFlowLayout(column: kColumnNumber, row: kRowNumber)
// collectionView
let collection = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
collection.backgroundColor = ThemeColor(hexStr: "#F8F8F8")
collection.register(cellType: ChatMoreMenuCell.self)
collection.showsHorizontalScrollIndicator = true
collection.showsVerticalScrollIndicator = true
collection.dataSource = self
collection.delegate = self
collection.isPagingEnabled = true
return collection
}()
lazy var pageControl: UIPageControl = {
let pager = UIPageControl()
pager.backgroundColor = .clear
pager.pageIndicatorTintColor = .white
pager.currentPageIndicatorTintColor = ThemeColor(hexStr: "#000000")
pager.currentPage = 0
pager.isHidden = true
pager.numberOfPages = self.dataSource.count / kMoreMenuCellNumberOfOnePage + (self.dataSource.count % kMoreMenuCellNumberOfOnePage == 0 ? 0 : 1)
return pager
}()
// MARK: - life cycle
override init(frame: CGRect) {
super.init(frame: frame)
makeUI()
reloadData()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
makeUI()
reloadData()
}
func makeUI() {
self.backgroundColor = ThemeColor(hexStr: "#F8F8F8")
addSubview(pageControl)
addSubview(collectionView)
pageControl.snp.makeConstraints { make in
make.bottom.equalToSuperview().offset(-SafeAraeBottomHeight)
make.centerX.equalToSuperview()
make.height.equalTo(30)
}
collectionView.snp.makeConstraints { make in
make.top.left.right.equalToSuperview()
make.bottom.equalTo(pageControl.snp.top)
}
}
open func reloadData() {
self.needsUpdateConstraints()
self.layoutIfNeeded()
UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut, animations: {
self.pageControl.alpha = 1.0
self.pageControl.isHidden = false
}, completion: nil)
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}
// MARK: - UICollectionViewDataSource
extension ChatMoreMenuView: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(for: indexPath, cellType: ChatMoreMenuCell.self)
if let model = dataSource[safe: indexPath.row] {
cell.model = model
}
return cell
}
}
// MARK: - UICollectionViewDelegate
extension ChatMoreMenuView: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let model = dataSource[safe: indexPath.row] {
delegate?.menu(self, DidSelected: model.type!)
}
}
}
extension ChatMoreMenuView {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == collectionView {
let offsetX = scrollView.contentOffset.x
let index = offsetX / ScreenWidth
pageControl.currentPage = Int(index)
}
}
}
class ChatKeyboardFlowLayout: UICollectionViewFlowLayout {
// item
fileprivate var attributesArr: [UICollectionViewLayoutAttributes] = []
fileprivate var col: Int = 0
fileprivate var row: Int = 0
init(column: Int, row: Int) {
super.init()
self.col = column
self.row = row
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: -
override func prepare() {
super.prepare()
let itemWH: CGFloat = ScreenWidth / CGFloat(col)
// itemSize
itemSize = CGSize(width: itemWH, height: itemWH)
minimumLineSpacing = 0
minimumInteritemSpacing = 0
scrollDirection = .horizontal
// collectionView
collectionView?.isPagingEnabled = true
collectionView?.showsHorizontalScrollIndicator = false
collectionView?.showsVerticalScrollIndicator = true
let insertMargin = (collectionView!.bounds.height - CGFloat(row) * itemWH) * 0.5
collectionView?.contentInset = UIEdgeInsets(top: insertMargin, left: 0, bottom: insertMargin, right: 0)
var page = 0
let itemsCount = collectionView?.numberOfItems(inSection: 0) ?? 0
for itemIndex in 0..<itemsCount {
let indexPath = IndexPath(item: itemIndex, section: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
page = itemIndex / (col * row)
// , x, y
let x = itemSize.width * CGFloat(itemIndex % Int(col)) + (CGFloat(page) * ScreenWidth)
let y = itemSize.height * CGFloat((itemIndex - page * row * col) / col)
attributes.frame = CGRect(x: x, y: y, width: itemSize.width, height: itemSize.height)
//
attributesArr.append(attributes)
}
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var rectAttributes: [UICollectionViewLayoutAttributes] = []
_ = attributesArr.map({
if rect.contains($0.frame) {
rectAttributes.append($0)
}
})
return rectAttributes
}
override var collectionViewContentSize: CGSize {
let size: CGSize = super.collectionViewContentSize
let collectionViewWidth: CGFloat = self.collectionView!.frame.size.width
let nbOfScreen: Int = Int(ceil(size.width / collectionViewWidth))
let newSize: CGSize = CGSize(width: collectionViewWidth * CGFloat(nbOfScreen), height: size.height)
return newSize
}
}

View File

@@ -0,0 +1,25 @@
//
// ChatMoreMnueConfig.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import Foundation
class ChatMoreMnueConfig: NSObject {
var title: String?
var image: String?
var type: ChatMoreMenuType?
init(title: String, image: String, type: ChatMoreMenuType) {
super.init()
self.title = title
self.image = image
self.type = type
}
required override init() { }
}

View File

@@ -13,7 +13,7 @@ protocol ChatBaseCellProtocol: NSObjectProtocol {
class ChatBaseCell: UITableViewCell, Reusable{
weak var delegate: ChatBaseCellProtocol?
var model:ChatBaseObject? {
var model:ChatSessionProtocol? {
didSet {
guard let _ = model else {return}
layoutMessageCell()

View File

@@ -0,0 +1,71 @@
//
// ChatListCell.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/29.
//
import UIKit
import Reusable
class ChatListCell: UITableViewCell, Reusable {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(backView)
backView.addSubview(avatarImgView)
backView.addSubview(textLb)
backView.addSubview(nameLb)
backView.addSubview(dateLb)
}
private lazy var backView: UIView = {
let view = UIView()
view.backgroundColor = ThemeColor(hexStr: "#525566")
view.layer.masksToBounds = true
return view
}()
private lazy var avatarImgView: UIImageView = {
let imageView = UIImageView()
imageView.isUserInteractionEnabled = true
imageView.layer.masksToBounds = true
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = 30
return imageView
}()
private lazy var textLb: UILabel = {
let label = UILabel()
label.textColor = UIColor(white: 1, alpha: 0.8)
label.font = UIFont.systemFont(ofSize: 14)
return label
}()
private lazy var nameLb: UILabel = {
let label = UILabel()
label.textColor = .white
label.font = UIFont.systemFont(ofSize: 15, weight: .medium)
return label
}()
private lazy var dateLb: UILabel = {
let label = UILabel()
label.textColor = .red
label.font = UIFont.systemFont(ofSize: 12, weight: .light)
return label
}()
private lazy var badgeLb: UILabel = {
let label = UILabel()
label.textColor = .white
label.backgroundColor = .red
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 11)
return label
}()
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@@ -85,8 +85,6 @@ class PlanetStarVC: BaseViewController,HiddenNavigationBarProtocol {
self?.navigationController?.pushViewController(chatVC, animated: true)
}
}
var giftModel:PlanetStarModel?

View File

@@ -62,7 +62,6 @@ make.size.equalTo(CGSize(width: 14, height: 14))
}
@objc func privacyRecognizer() {
//TODO:
let web = WebViewController(url: "yinmeng/\(H5Utils.privacy.rawValue)")
self.navigationController?.pushViewController(web, animated: true)
}

View File

@@ -71,7 +71,7 @@ class UserInfoVC: BaseViewController, HiddenNavigationBarProtocol {
}
@objc func logoutBtnAction() {
//TODO: 退
AuthViewModel.authVM.logout()
}
private lazy var backImgView: UIImageView = {
@@ -135,7 +135,7 @@ class UserInfoVC: BaseViewController, HiddenNavigationBarProtocol {
private lazy var logoutBtn: UIButton = {
let button = UIButton(type: .custom)
button.setBackgroundImage(UIImage.gradient([ThemeColor(hexStr: "#FFC926"), ThemeColor(hexStr: "#FFE784")], radius: 0), for: .normal)
button.setBackgroundImage(UIImage.gradient([ThemeColor(hexStr: "#FF60FD"), ThemeColor(hexStr: "#8974FF"), ThemeColor(hexStr: "#69EBFF")], radius: 0), for: .normal)
button.setTitle("退出登录", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)

View File

@@ -6,18 +6,19 @@
//
import Foundation
import RxSwift
class UserViewModel: NSObject {
static let userVM = UserViewModel.init()
let userInfo = PublishSubject<UserObject>()
func getUserInfo(uid:Int) {
let params = ["uid":uid]
RequestGet(path: "user/get", parma: params) { data in
if let info = Deserialized<UserObject>.toModel(with: data) {
print("用户信息是")
if var info = Deserialized<UserObject>.toModel(with: data) {
self.userInfo.onNext(info)
}
} fail: { code, message in
}
}
}