Create room avatar view.

This commit is contained in:
SBiOSoftWhare 2021-02-21 23:47:20 +01:00
parent d451788b35
commit e134633cf4
2 changed files with 224 additions and 0 deletions

View file

@ -0,0 +1,149 @@
//
// Copyright 2020 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import UIKit
import Reusable
final class RoomAvatarView: UIView, NibOwnerLoadable, Themable {
// MARK: - Properties
// MARK: Outlets
@IBOutlet private weak var avatarImageView: MXKImageView!
@IBOutlet private weak var cameraBadgeContainerView: UIView!
// MARK: Private
private var theme: Theme?
private var isHighlighted: Bool = false {
didSet {
self.updateView()
}
}
// MARK: Public
var action: (() -> Void)?
// MARK: Setup
private func commonInit() {
self.setupAvatarImageView()
self.setupGestureRecognizer()
self.vc_setupAccessibilityTraitsButton(withTitle: VectorL10n.roomAvatarViewAccessibilityLabel, hint: VectorL10n.roomAvatarViewAccessibilityHint, isEnabled: true)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.loadNibContent()
self.commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.loadNibContent()
self.commonInit()
}
// MARK: - Lifecycle
override func layoutSubviews() {
super.layoutSubviews()
self.avatarImageView.layer.cornerRadius = self.avatarImageView.bounds.height/2
}
// MARK: - Public
func fill(with viewData: RoomAvatarViewData) {
self.updateAvatarImageView(with: viewData)
// Fix layoutSubviews not triggered issue
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.setNeedsLayout()
}
}
func update(theme: Theme) {
self.theme = theme
}
// MARK: - Private
private func setupGestureRecognizer() {
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(buttonAction(_:)))
gestureRecognizer.minimumPressDuration = 0
self.addGestureRecognizer(gestureRecognizer)
}
private func setupAvatarImageView() {
self.avatarImageView.defaultBackgroundColor = UIColor.clear
self.avatarImageView.enableInMemoryCache = true
self.avatarImageView.layer.masksToBounds = true
}
private func updateAvatarImageView(with viewData: RoomAvatarViewData) {
guard let avatarImageView = self.avatarImageView else {
return
}
let defaultavatarImage = AvatarGenerator.generateAvatar(forMatrixItem: viewData.roomId, withDisplayName: viewData.roomDisplayName)
if let avatarUrl = viewData.avatarUrl {
avatarImageView.setImageURI(avatarUrl,
withType: nil,
andImageOrientation: .up,
toFitViewSize: avatarImageView.frame.size,
with: MXThumbnailingMethodScale,
previewImage: defaultavatarImage,
mediaManager: viewData.mediaManager)
} else {
avatarImageView.image = defaultavatarImage
}
avatarImageView.contentMode = .scaleAspectFill
self.cameraBadgeContainerView.isHidden = viewData.avatarUrl != nil
}
private func updateView() {
// TODO: Handle highlighted state
}
// MARK: - Actions
@objc private func buttonAction(_ sender: UILongPressGestureRecognizer) {
let isBackgroundViewTouched = sender.vc_isTouchingInside()
switch sender.state {
case .began, .changed:
self.isHighlighted = isBackgroundViewTouched
case .ended:
self.isHighlighted = false
if isBackgroundViewTouched {
self.action?()
}
case .cancelled:
self.isHighlighted = false
default:
break
}
}
}

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RoomAvatarView" customModule="Riot" customModuleProvider="target">
<connections>
<outlet property="avatarImageView" destination="ln9-Sd-GKd" id="9Zd-LM-hgl"/>
<outlet property="cameraBadgeContainerView" destination="0YT-CK-WjK" id="T31-nq-8PB"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="80" height="80"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iK1-yG-fEu">
<rect key="frame" x="0.0" y="0.0" width="80" height="80"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ln9-Sd-GKd" customClass="MXKImageView">
<rect key="frame" x="0.0" y="0.0" width="80" height="80"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0YT-CK-WjK">
<rect key="frame" x="56" y="56" width="24" height="24"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="capture_avatar" translatesAutoresizingMaskIntoConstraints="NO" id="vGE-Mx-xPX">
<rect key="frame" x="0.0" y="0.0" width="24" height="24"/>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="24" id="AIT-k4-SJZ"/>
<constraint firstItem="vGE-Mx-xPX" firstAttribute="leading" secondItem="0YT-CK-WjK" secondAttribute="leading" id="IoL-FC-x3t"/>
<constraint firstAttribute="trailing" secondItem="vGE-Mx-xPX" secondAttribute="trailing" id="KDL-CV-LNm"/>
<constraint firstItem="vGE-Mx-xPX" firstAttribute="top" secondItem="0YT-CK-WjK" secondAttribute="top" id="PLP-FV-9fe"/>
<constraint firstAttribute="bottom" secondItem="vGE-Mx-xPX" secondAttribute="bottom" id="bIo-ge-7Ud"/>
<constraint firstAttribute="width" constant="24" id="ugV-gr-fbC"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="0YT-CK-WjK" secondAttribute="trailing" id="8HT-uc-Dd2"/>
<constraint firstAttribute="trailing" secondItem="ln9-Sd-GKd" secondAttribute="trailing" id="ABF-Wz-ZZy"/>
<constraint firstAttribute="height" constant="80" id="GdE-dy-bxN"/>
<constraint firstAttribute="width" constant="80" id="NCu-Xg-4p3"/>
<constraint firstAttribute="bottom" secondItem="ln9-Sd-GKd" secondAttribute="bottom" id="NZp-ao-R0Q"/>
<constraint firstItem="ln9-Sd-GKd" firstAttribute="top" secondItem="iK1-yG-fEu" secondAttribute="top" id="VZt-Uu-toa"/>
<constraint firstItem="ln9-Sd-GKd" firstAttribute="leading" secondItem="iK1-yG-fEu" secondAttribute="leading" id="jEs-Ac-ock"/>
<constraint firstAttribute="bottom" secondItem="0YT-CK-WjK" secondAttribute="bottom" id="wIN-TR-RZm"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="iK1-yG-fEu" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="GZx-C7-FF8"/>
<constraint firstAttribute="trailing" secondItem="iK1-yG-fEu" secondAttribute="trailing" id="UPO-MZ-XUZ"/>
<constraint firstAttribute="bottom" secondItem="iK1-yG-fEu" secondAttribute="bottom" id="g7y-SL-f3s"/>
<constraint firstItem="iK1-yG-fEu" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="imn-uW-TTP"/>
</constraints>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-433" y="-802"/>
</view>
</objects>
<resources>
<image name="capture_avatar" width="25" height="25"/>
</resources>
</document>