请依照上面的xib文件全部检查//
// NewCoverImageContainerView.swift
// SurveillanceHome
//
// Created by MaCong on 2025/12/8.
// Copyright © 2025 tplink. All rights reserved.
//
import UIKit
import SnapKit
class NewCoverImageContainerView: UIView {
// MARK: - IBOutlets (now created in code)
var coverImageView: UIImageView!
var maskImageView: UIImageView!
var maskLabel: UILabel!
var helpButton: UIButton?
var helpLabel: UILabel!
var labelToCenterConstraint: NSLayoutConstraint?
// Constraints (optional outlets)
@IBOutlet weak var coverBGTrailConst: NSLayoutConstraint?
@IBOutlet weak var coverBGLeadingConst: NSLayoutConstraint?
@IBOutlet weak var coverTrailConst: NSLayoutConstraint?
@IBOutlet weak var coverLeadingConst: NSLayoutConstraint?
// Private properties
private var statusImageViews = [UIImageView]()
private var isCollected: Bool = false {
didSet {
let image = isCollected ? TPImageLiteral("device_have_collect_card") : TPImageLiteral("device_not_collect_card")
collectButton.setImage(image, for: .normal)
}
}
private lazy var collectButton: UIButton = {
let view = UIButton()
view.setImage(TPImageLiteral("device_not_collect_card"), for: .normal)
view.addTarget(self, action: #selector(collectButtonClicked), for: .touchUpInside)
return view
}()
var collectAction: ((Bool) -> Void)?
var helpAction: (() -> Void)?
/* 云存储、WiFi状态、报警状态 */
//首页隐藏图标
private let numberOfStatusImages = 0
private let needHideMask: Int = 1
// MARK: - Initializers
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
setupViews()
setupConstraints()
awakeFromNib()
}
// MARK: - Setup Views
private func setupViews() {
// Create subviews
coverImageView = UIImageView()
coverImageView.contentMode = .scaleToFill
coverImageView.clipsToBounds = true
coverImageView.isUserInteractionEnabled = false
maskImageView = UIImageView()
maskImageView.contentMode = .scaleToFill
maskImageView.clipsToBounds = true
maskImageView.isUserInteractionEnabled = false
maskImageView.tag = 3
maskLabel = UILabel()
maskLabel.tag = 4
maskLabel.text = "无设备"
maskLabel.font = UIFont(name: "PingFangSC-Regular", size: 12)
maskLabel.textColor = UIColor(white: 1.0, alpha: 1.0)
maskLabel.textAlignment = .center
maskLabel.backgroundColor = .clear
maskLabel.adjustsFontSizeToFitWidth = false
maskLabel.baselineAdjustment = .alignBaselines
maskLabel.numberOfLines = 1
helpButton = UIButton(type: .system)
helpButton?.setTitle(LocalizedString(key: deviceListHelp), for: .normal)
helpButton?.titleLabel?.font = UIFont.systemFont(ofSize: 10)
helpButton?.setTitleColor(.tpbTextPrimary, for: .normal)
helpButton?.layer.borderWidth = 1
helpButton?.layer.borderColor = UIColor.tpbTextDisabled.cgColor
helpButton?.addTarget(self, action: #selector(helpButtonClicked), for: .touchUpInside)
helpLabel = UILabel()
helpLabel.text = LocalizedString(key: deviceListHelp)
helpLabel.font = UIFont.systemFont(ofSize: 10)
helpLabel.textColor = .tpbTextSecondary
helpLabel.textAlignment = .right
backgroundColor = UIColor(white: 0.0, alpha: 0.0)
layer.cornerRadius = 2
layer.masksToBounds = true
addSubview(coverImageView)
addSubview(maskImageView)
addSubview(maskLabel)
addSubview(collectButton)
if let hb = helpButton, let hl = helpLabel {
addSubview(hb)
addSubview(hl)
}
}
// MARK: - Setup Constraints with SnapKit
private func setupConstraints() {
coverImageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
maskImageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
maskLabel.snp.makeConstraints { make in
make.leading.trailing.equalToSuperview()
make.centerY.equalToSuperview()
make.height.equalTo(17)
}
collectButton.snp.makeConstraints { make in
make.top.equalToSuperview().offset(8)
make.trailing.equalToSuperview().offset(-8)
make.width.height.equalTo(26)
}
helpButton?.snp.makeConstraints { make in
make.centerY.equalTo(helpLabel!)
make.trailing.equalToSuperview().offset(-8)
make.width.greaterThanOrEqualTo(30)
}
helpLabel?.snp.makeConstraints { make in
make.centerY.equalTo(maskLabel!)
make.trailing.equalTo(helpButton!.snp.leading).offset(-4)
make.trailing.lessThanOrEqualToSuperview().offset(-8)
self.labelToCenterConstraint = make.centerX.equalToSuperview().constraint
}
// Initialize optional constraints as zero constants
coverBGTrailConst = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
coverBGLeadingConst = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
coverTrailConst = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
coverLeadingConst = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
}
// MARK: - awakeFromNib模拟
override func awakeFromNib() {
super.awakeFromNib()
#if MERCURY_SURVEILLANCE
layer.cornerRadius = 0
#endif
helpButton?.layer.borderWidth = 1
helpButton?.layer.borderColor = UIColor.tpbTextDisabled.cgColor
helpButton?.addTarget(self, action: #selector(helpButtonClicked), for: .touchUpInside)
let isBigImage = bounds.height > 80
for i in 0..<numberOfStatusImages {
let imageView = UIImageView()
let interval: CGFloat = 16 + (isBigImage ? 2 : 0)
let minX: CGFloat = TPLocalizationUtils.isRTL() ? CGFloat(i) * interval + 2 : bounds.maxX - CGFloat(i + 1) * interval - 2
let minY: CGFloat = isBigImage ? 2 : 0
let rect = CGRect(x: minX, y: minY, width: 16, height: 16)
imageView.frame = rect
addSubview(imageView)
imageView.isHidden = true
imageView.autoresizingMask = [TPLocalizationUtils.isRTL() ? .flexibleRightMargin : .flexibleLeftMargin, .flexibleBottomMargin]
statusImageViews.append(imageView)
statusImageViews.forEach { $0.isHidden = true }
}
self.addSubview(collectButton)
collectButton.isHidden = true
}
// MARK: - Actions
@objc private func collectButtonClicked() {
collectAction?(!isCollected)
}
@objc private func helpButtonClicked() {
helpAction?()
}
// MARK: - Public Methods (完全复制原逻辑)
func shouldShowCollectButton(device: TPSSDeviceForDeviceList, channel: TPSSChannelInfo? = nil, isCard: Bool) {
let isVms = TPAppContextFactory.shared().isVmsLogin
collectButton.isHidden = (device.displayType == .solar || device.listType == .local || !isCard || (TPSSAppContext.shared.loginType == .personal ? false : TPSSAppContext.shared.isVmsDeviceListFavoriteOldVersion)) ? true : false
if device.deviceType == .IPC {
isCollected = isVms ? device.isVMSFavorited : device.isCollected
} else if device.deviceType == .NVR {
if channel != nil {
isCollected = isVms ? channel!.isVMSFavorited : device.isCollected && device.collectChannels.contains(channel!.channelId as NSNumber)
} else {
isCollected = isVms ? device.isVMSFavorited : device.isCollected
}
}
}
func configureCoverWith(size: TPSSDeviceForDeviceList.CoverImageSize,
device: TPSSDeviceForDeviceList,
channel: TPSSChannelInfo? = nil,
hideMaskIfNeeded: Bool = false,
isCard: Bool = false,
folded: Bool = false,
leadingConst: NSLayoutConstraint? = nil,
trailConst: NSLayoutConstraint? = nil,
isSmall: Bool = false,
isModelCover: Bool = false,
noDevice: Bool = false,
isHideLogo: Bool = false) {
var noDevices = true
if((channel) != nil){
noDevices = !device.activeChannelsInfo.contains(channel!)
}
shouldShowCollectButton(device: device, channel: channel, isCard: isCard)
var coverImage:UIImage? = device.displayType == .solar ? TPSSDeviceForDeviceList.defaultSolarCoverImage(of: size) : TPSSDeviceForDeviceList.defaultCoverImage(of: size)
if isModelCover {
coverImage = TPSSDeviceForDeviceList.getDeviceModelImage(type: .IPC, model: noDevice ? "" : channel?.deviceModel ?? "")
}
if(!noDevices){
coverImage = device.coverImage(of: size, channelID: channel?.channelId.intValue ?? -1, listType: device.listType)
}
if hideMaskIfNeeded && !maskImageView.isHidden {
maskImageView.isHidden = maskImageView.tag == needHideMask && coverImage != nil
}
coverImageView.image = coverImage ?? (device.displayType == .solar ? TPSSDeviceForDeviceList.defaultSolarCoverImage(of: size) : (isModelCover ? TPSSDeviceForDeviceList.getDeviceModelImage(type: .IPC, model: noDevice ? "" : channel?.deviceModel ?? "") : TPSSDeviceForDeviceList.defaultCoverImage(of: size)))
var isFisheye = false
if TPSSAppContext.shared.isVmsLogin && device.listType == .remote {
isFisheye = coverImage != nil && device.coverImageIsFisheye(of: size, channelID: channel?.channelId.intValue ?? -1, listType: device.listType)
}
if (!isFisheye) {
if let channelInfo = channel, device.displayType == .NVR {
isFisheye = coverImage != nil && channelInfo.supportsFisheye
} else {
isFisheye = coverImage != nil && device.supportFishEye
}
}
var isPano = false
if let channelInfo = channel, device.displayType == .NVR {
isPano = coverImage != nil && channelInfo.isSupportSplicingSetting
} else {
isPano = coverImage != nil && device.supportPano
}
let imageWidth = coverImage?.size.width ?? 1
let imageHeight = coverImage?.size.height ?? 1
if (!isFisheye && imageWidth > 1.1 && abs(imageWidth - imageHeight) < 1) {
isFisheye = true;
}
coverImageView.contentMode = isFisheye ? isCard ? .scaleAspectFit : .scaleAspectFill : .scaleToFill
isPano = ( isPano || (imageWidth / imageHeight) >= 3)
backgroundColor = isFisheye ? .tpbFisheyeBackground : .clear
if (device.displayType != .solar) {
let oldImg = coverImageView.image;
let newImg = cropFishScaleImg(img: oldImg, isFishEye: isFisheye);
if (oldImg != newImg) {
coverImageView.image = newImg;
coverImageView.contentMode = isCard ? .scaleAspectFit : .scaleAspectFill
backgroundColor = .tpbFisheyeBackground
}
if (isPano) {
coverImageView.contentMode = .scaleAspectFill
backgroundColor = .clear
}
if (isCard && (isFisheye || oldImg != newImg) && (!folded || device.deviceType == .IPC)) {
coverImageView.contentMode = .scaleAspectFit;
}
}
let block = {(constant:CGFloat) in
self.coverBGTrailConst?.constant = constant;
self.coverBGLeadingConst?.constant = constant;
self.coverTrailConst?.constant = constant;
self.coverLeadingConst?.constant = constant;
leadingConst?.constant = constant;
trailConst?.constant = constant;
}
block(0);
if device.displayType == .solar {
coverImageView.contentMode = .scaleAspectFit
coverImageView.backgroundColor = .tpbBackground
}
if isModelCover && (noDevice || coverImage == nil) {
coverImageView.contentMode = .scaleAspectFit
coverImageView.backgroundColor = .tpbBackground
}
if isHideLogo && coverImage == nil {
coverImageView.isHidden = true
} else {
coverImageView.isHidden = false
}
guard let imgSize = coverImageView.image?.size, !isFisheye, imgSize.height > imgSize.width else { return }
backgroundColor = .tpbFisheyeBackground
coverImageView.contentMode = .scaleAspectFill;
var hMargin : CGFloat = 10;
if (isCard) {
if ((!folded) || device.displayType == .IPC) {
hMargin = 70;
} else {
hMargin = 30;
}
} else {
if (isSmall) {
hMargin = 10;
} else {
hMargin = 20;
}
}
block(hMargin);
}
func configureWith(cloudStorageEnabled: Bool = false,
supportsAlarm: Bool = false,
alarm: Bool = true,
noDevice: Bool = false,
channelOffline: Bool = false,
channelHidden: Bool = false,
channelUnAuth: Bool = false,
channelUninitialized: Bool = false,
offline: Bool = false,
nvrOffline: Bool = false,
ipcOffline: Bool = false,
offlineTime: String = "",
notInSharePeriod: Bool = false,
notShareEnable: Bool = false,
notConnected: Bool = false,
supportConnectionInfo: Bool = false,
connectedViaWifi: Bool = false,
wifiRssi: Int = 0,
showHelp: Bool = false,
playButtonHidden: Bool = false,
size: TPSSDeviceForDeviceList.CoverImageSize,
showText: Bool = true,
showIcons: Bool = true,
hasNoVmsLicense: Bool = false,
isChannel: Bool = false) {
let showAlarm = supportsAlarm && !noDevice
let showWifiStatus = supportConnectionInfo && connectedViaWifi && !(offline || nvrOffline || ipcOffline)
let showCloudStorage = cloudStorageEnabled
let images: [UIImage] = [showAlarm ? (alarm ? TPImageLiteral("devicelist_indicator_alarm_on") : TPImageLiteral("devicelist_indicator_alarm_off")) : nil,
showWifiStatus ? UIImage(named: "common_wifi_indicator\(wifiRssi)") : nil,
showCloudStorage ? TPImageLiteral("cloud_label") : nil].compactMap {$0}
for i in 0..<statusImageViews.count {
if i >= images.count {
statusImageViews[i].isHidden = true
} else {
statusImageViews[i].isHidden = !showIcons
statusImageViews[i].image = images[i]
}
}
let deviceOffline = offline || nvrOffline || ipcOffline || channelOffline
if noDevice || deviceOffline || notInSharePeriod || notShareEnable || notConnected || channelHidden || hasNoVmsLicense {
maskImageView.isHidden = false
maskLabel.isHidden = false
maskImageView.image = nil
maskImageView.backgroundColor = .tpbDeviceMask
maskImageView.contentMode = .scaleAspectFit
}
maskLabel.numberOfLines = 3
maskImageView.tag = 0
if deviceOffline {
if isChannel && noDevice {
maskLabel.text = LocalizedString(key: deviceListNoSuchDevice)
}
else if isChannel && channelUnAuth {
maskLabel.text = LocalizedString(key: NVRAddIPCDeviceNotCertified)
} else if isChannel && channelUninitialized {
maskLabel.text = LocalizedString(key: multiWindowPlayerUninitialized)
}
else {
let basicText = notInSharePeriod ? LocalizedString(key: deviceListNotInSharePeriod) : LocalizedString(key: deviceListDeviceNotOnline)
if !offlineTime.isEmpty {
maskLabel.numberOfLines = 0
let firstLine = basicText
let secondLine = String(format: LocalizedString(key: deviceListOfflineTimeFormat), offlineTime)
let text = NSMutableAttributedString(string: "\(firstLine)\n\(secondLine)")
text.addAttributes([NSAttributedString.Key.font: UIFont.projectFont(ofSize: 12)], range: NSMakeRange(0, firstLine.count))
let style = NSMutableParagraphStyle()
style.lineSpacing = 8
style.alignment = .center
text.addAttributes([NSAttributedString.Key.paragraphStyle: style], range: NSMakeRange(0, text.length))
text.addAttributes([NSAttributedString.Key.font: UIFont.projectFont(ofSize: 10)], range: NSMakeRange(firstLine.count + 1, secondLine.count))
maskLabel.attributedText = text
} else {
maskLabel.text = basicText
}
}
} else if noDevice {
maskLabel.text = LocalizedString(key: deviceListNoSuchDevice)
} else if notShareEnable {
maskLabel.text = LocalizedString(key: deviceListNotShareEnable)
} else if notInSharePeriod && !deviceOffline {
maskLabel.text = LocalizedString(key: deviceListNotInSharePeriod)
} else if channelUnAuth {
maskLabel.text = LocalizedString(key: NVRAddIPCDeviceNotCertified)
} else if channelHidden {
maskLabel.text = LocalizedString(key: deviceListChannelHidden)
} else if notConnected {
maskLabel.text = LocalizedString(key: wirelessDirectNotConnected)
} else if hasNoVmsLicense {
maskLabel.text = LocalizedString(key: deviceListCloudVmsWithoutLicenseMaskLabel)
} else {
maskImageView.isHidden = playButtonHidden
maskLabel.isHidden = true
switch size {
case .small:
maskImageView.image = TPImageLiteral("devicelist_preview_small")
maskImageView.contentMode = .scaleAspectFit
case .medium:
maskImageView.image = TPImageLiteral("devicelist_preview_medium")
maskImageView.contentMode = .center
default:
maskImageView.image = TPImageLiteral("devicelist_preview_large")
maskImageView.contentMode = .center
}
maskImageView.backgroundColor = .clear
maskImageView.tag = needHideMask
}
if !showText {
maskLabel.text = ""
}
if helpButton != nil {
if showHelp {
helpButton?.isHidden = false
helpLabel.isHidden = false
labelToCenterConstraint?.constant = -22
} else {
helpButton?.isHidden = true
helpLabel.isHidden = true
labelToCenterConstraint?.constant = 0
}
}
}
}
// MARK: - Extension: configure overloads (保持原样)
extension NewCoverImageContainerView {
enum CoverType {
case play
case selection
}
func configure(ipc: TPSSDeviceForDeviceList, size: TPSSDeviceForDeviceList.CoverImageSize = .medium, type: CoverType = .play, isCard:Bool = false, folded:Bool=false) {
shouldShowCollectButton(device: ipc, isCard: isCard)
let showAccessory = size != .small
let showDetailText = showAccessory && size != .medium
let showPlayButton = (ipc.displayType != .solar && type == .play)
if ipc.listType == .remote {
configureWith(cloudStorageEnabled: ipc.cloudStorageService()?.serviceState.isValid ?? false,
supportsAlarm: ipc.supportMessage && ipc.displayOnline && !ipc.isSharedDevice,
alarm: ipc.messageEnable,
ipcOffline: !ipc.displayOnline,
offlineTime: showDetailText ? ipc.offlineTime : "",
notInSharePeriod: (ipc.isSharedDevice && !ipc.isInSharePeriod),
notShareEnable: (ipc.isSharedDevice && !ipc.isShareEnable),
supportConnectionInfo: ipc.supportConnectInfo,
connectedViaWifi: ipc.linkType == .wifi,
wifiRssi: ipc.linkRssi,
showHelp: showAccessory && !ipc.displayOnline && !ipc.isSharedDevice,
playButtonHidden: !showPlayButton,
size: size,
showText: showAccessory,
showIcons: showAccessory,
hasNoVmsLicense: ipc.isLicenseNotActive)
} else {
configureWith(ipcOffline: !ipc.displayOnline,
offlineTime: showDetailText ? ipc.offlineTime : "",
supportConnectionInfo: ipc.supportConnectInfo,
connectedViaWifi: ipc.linkType == .wifi,
wifiRssi: ipc.linkRssi,
showHelp: showAccessory && !ipc.displayOnline && !ipc.isSharedDevice,
playButtonHidden: !showPlayButton,
size: size,
showText: showAccessory,
showIcons: showAccessory)
}
configureCoverWith(size: size, device: ipc, channel: ipc.channelsInfo.first, hideMaskIfNeeded: true, isCard: isCard, folded:folded)
statusImageViews.forEach { $0.isHidden = true }
}
func configure(channel: TPSSChannelInfo, nvr: TPSSDeviceForDeviceList, size: TPSSDeviceForDeviceList.CoverImageSize = .medium, type: CoverType = .play, isCard:Bool = false, folded:Bool = false, leadingConst:NSLayoutConstraint? = nil, trialConst:NSLayoutConstraint? = nil, isSmall:Bool=false, isSigleChannel:Bool = false, isHideLogo : Bool = false) {
let showAccessory = size != .small
let showPlayButton = type == .play && !isSigleChannel
shouldShowCollectButton(device: nvr, channel: channel, isCard: isCard)
if nvr.listType == .remote {
configureWith(cloudStorageEnabled: nvr.cloudStorageService(channel: channel)?.serviceState.isValid ?? false,
supportsAlarm: channel.supportsMessagePush && channel.online && !nvr.isSharedDevice,
alarm: channel.messageEnable,
noDevice: !nvr.activeChannelsInfo.contains(channel),
channelOffline: !channel.online,
channelUnAuth: channel.authResult == 1,
channelUninitialized: channel.authResult == 3,
notInSharePeriod: (nvr.isSharedDevice && !channel.isInSharePeriod),
notShareEnable: (nvr.isSharedDevice && !channel.isShareEnable),
showHelp: !channel.online && channel.authResult == 0 && channel.active,
playButtonHidden: !showPlayButton,
size: size,
showText: showAccessory,
showIcons: showIcons,
hasNoVmsLicense: channel.isLicenseNotActive,
isChannel: true)
} else {
configureWith(noDevice: !nvr.activeChannelsInfo.contains(channel),
channelOffline: !channel.online,
channelUnAuth: channel.authResult == 1,
channelUninitialized: channel.authResult == 3,
showHelp: !channel.online && channel.authResult == 0,
playButtonHidden: !showPlayButton,
size: size,
showText: showAccessory,
showIcons: showIcons,
isChannel: true)
}
configureCoverWith(size: size, device: nvr, channel: channel, hideMaskIfNeeded: true, isCard:isCard, folded: folded, leadingConst: leadingConst, trailConst: trialConst, isSmall: isSmall, isHideLogo: !isCard && isHideLogo)
statusImageViews.forEach { $0.isHidden = true }
}
func configure(nvr: TPSSDeviceForDeviceList, size: TPSSDeviceForDeviceList.CoverImageSize = .medium, type: CoverType = .play) {
let showAccessory = size != .small
let showPlayButton = type == .play
let showDetailText = showAccessory && size != .medium
let channelHidden = nvr.channelsInfo.count == 0 && nvr.allChannelsInfo.count != 0
var noDevice = nvr.activeChannelsInfo.count == 0 && !channelHidden
if nvr.isSharedFromOthers {
for channel in nvr.activeChannelsInfo {
if channel.isSharedFromOthers {
noDevice = false
break
} else {
noDevice = true
}
}
}
if nvr.listType == .remote {
configureWith(noDevice: noDevice,
channelHidden: channelHidden,
nvrOffline: !nvr.displayOnline,
offlineTime: showDetailText ? nvr.offlineTime : "",
showHelp: showAccessory && !nvr.displayOnline && !nvr.isSharedDevice,
playButtonHidden: !showPlayButton,
size: size,
showText: showAccessory,
showIcons: showIcons,
hasNoVmsLicense: false)
} else {
configureWith(noDevice: noDevice,
channelHidden: channelHidden,
nvrOffline: !nvr.displayOnline,
offlineTime: showDetailText ? nvr.offlineTime : "",
showHelp: showAccessory && !nvr.displayOnline && !nvr.isSharedDevice,
playButtonHidden: !showPlayButton,
size: size,
showText: showAccessory,
showIcons: showIcons)
}
configureCoverWith(size: size, device: nvr, channel: nil, hideMaskIfNeeded: true)
}
func showEmpty(size: TPSSDeviceForDeviceList.CoverImageSize = .medium) {
configureWith(playButtonHidden: true,
size: size,
showText: false,
showIcons: false)
coverImageView.image = TPSSDeviceForDeviceList.defaultCoverImage(of: size)
coverLeadingConst?.constant = 0
coverTrailConst?.constant = 0
}
}
// MARK: - Device Setting Extension
extension NewCoverImageContainerView {
func configure(device: TPSSDeviceForSetting, channel: TPSSChannelInfo?, size: TPSSDeviceForDeviceList.CoverImageSize = .medium, model: String = "") {
configureWith(playButtonHidden: true,
size: size,
showText: false,
showIcons: false)
let channelID = channel?.channelId.intValue ?? -1
let coverImage = device.coverImage(at: channelID, listType: device.deviceListType)
coverImageView.image = coverImage ?? device.defaultCoverImage(at: channelID, size: size, model: model)
var isFisheye = false
if TPSSAppContext.shared.isVmsLogin && device.deviceListType == .remote {
isFisheye = coverImage != nil && device.coverImageIsFisheye(at: channelID, listType: device.deviceListType)
} else {
if let channelInfo = channel {
isFisheye = coverImage != nil && channelInfo.supportsFisheye
} else {
isFisheye = coverImage != nil && device.isFishEye
}
}
if isFisheye {
coverImageView.contentMode = .scaleAspectFill
}
else if device.deviceType == .solar || coverImage == nil {
coverImageView.contentMode = .scaleAspectFit
coverImageView.backgroundColor = .tpbProgressBackground
coverImageView.layer.cornerRadius = 8
}
else {
var CorridorContentMode = UIView.ContentMode.scaleAspectFit
if let img = coverImage {
CorridorContentMode = img.size.height > img.size.width ? .scaleAspectFit : .scaleAspectFill
}
if let channelInfo = channel {
if channelInfo.supportCorridor {
coverImageView.contentMode = CorridorContentMode
coverImageView.backgroundColor = .tpbProgressBackground
} else if channelInfo.isSupportSplicingSetting {
coverImageView.contentMode = .scaleAspectFill
} else {
coverImageView.contentMode = .scaleToFill
}
} else if device.supportCorridor {
coverImageView.contentMode = CorridorContentMode
coverImageView.backgroundColor = .tpbProgressBackground
} else if device.isSupportSplicingSetting {
coverImageView.contentMode = .scaleAspectFill
} else {
coverImageView.contentMode = .scaleToFill
}
}
backgroundColor = isFisheye ? .tpbFisheyeBackground : .clear
}
}
// MARK: - Subclasses & Utilities
class CoverImageBigContainerView: NewCoverImageContainerView {
@IBOutlet weak var nvrChannelNameContainer: UIView!
@IBOutlet weak var nvrChannelNameLabel: UILabel!
}
extension UIImage {
class func pureColorImage(color: UIColor, size: CGSize) -> UIImage {
let size = CGSize(width: size.width.rounded(.awayFromZero), height: size.height.rounded(.awayFromZero)).getNotZeroSize()
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()!
context.setFillColor(color.cgColor)
context.fill(CGRect(origin: .zero, size: size))
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
class ExtendedButton: UIButton {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let rect = bounds.insetBy(dx: -bounds.width / 2, dy: -bounds.height / 2)
return rect.contains(point)
}
}
此外还有其他的报错,并且我要求不使用storyboard方式,要求全部使用纯代码实现,而且是使用snapkit布局
最新发布