Я пробовал некоторые решения из других публикаций, но мне не удалось решить вопрос, который я собираюсь опубликовать.
У меня есть собственный UIView, который рисует SoundWave и содержит UIScrollView.UIScrollView содержит основной UIView, который содержит два других пользовательских UIViews (маркер слева и справа) и UIImage, где я визуализирую звуковую волну.
private func initialize(){
print("\(logClassName) initialize in Frame: \(frame)")
//ScrollView
addSubview(scrollView)
scrollView.constraintToSuperViewEdges()
//WaveView
scrollView.addSubview(waveView)
waveView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
waveView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 0).isActive = true
waveView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: 0).isActive = true
waveView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
waveViewWidthConstraint = waveView.widthAnchor.constraint(equalToConstant: 1000)
NSLayoutConstraint.activate([waveViewWidthConstraint])
scrollView.contentSize = CGSize(width: waveViewWidthConstraint.constant, height: 0)
//SoundWaveImageView
waveView.addSubview(soundWaveImageView)
soundWaveImageView.constraintToSuperViewEdges()
//WaveView markers
//TimeMarker
waveView.addSubview(timeMarkerView)
timeMarkerView.topAnchor.constraint(equalTo: waveView.topAnchor).isActive = true
timeMarkerView.bottomAnchor.constraint(equalTo: waveView.bottomAnchor).isActive = true
timeMarkerView.widthAnchor.constraint(equalToConstant: 1).isActive = true
timerMarkerViewLeadingContraint = timeMarkerView.leadingAnchor.constraint(equalTo: waveView.leadingAnchor, constant: 20)
NSLayoutConstraint.activate([timerMarkerViewLeadingContraint])
//LeftMarker
waveView.addSubview(leftMarkerView)
leftMarkerView.topAnchor.constraint(equalTo: waveView.topAnchor).isActive = true
leftMarkerView.bottomAnchor.constraint(equalTo: waveView.bottomAnchor).isActive = true
leftMarkerView.widthAnchor.constraint(equalToConstant: leftMarkerView.triangleWidth).isActive = true
leftMarkerViewLeadingConstraint = leftMarkerView.leadingAnchor.constraint(equalTo: waveView.leadingAnchor, constant: 0)
NSLayoutConstraint.activate([leftMarkerViewLeadingConstraint])
//RightMarker
waveView.addSubview(rightMarkerView)
rightMarkerView.topAnchor.constraint(equalTo: waveView.topAnchor).isActive = true
rightMarkerView.bottomAnchor.constraint(equalTo: waveView.bottomAnchor).isActive = true
rightMarkerView.widthAnchor.constraint(equalToConstant: rightMarkerView.triangleWidth).isActive = true
rightMarkerViewLeadingConstraint = rightMarkerView.trailingAnchor.constraint(equalTo: waveView.leadingAnchor, constant: 50)
NSLayoutConstraint.activate([rightMarkerViewLeadingConstraint])
}
Как видно, основным UIView является ограничение по краямUIScrollView и ограничение ширины - это общая длина, которая изменяется в соответствии с потребностями.За это отвечает следующая функция:
private func updateWidthConstraintValue(_ newWidth:CGFloat){
waveViewWidthConstraint.constant = newWidth
scrollView.contentSize = CGSize(width: waveViewWidthConstraint.constant, height: 0)
}
При реализации масштабирования для UIScrollView он работает, но масштабируется как по вертикали, так и по горизонтали (как и ожидалось), но я хотел бы реализовать только по горизонтали.Пока у меня есть это:
func scrollViewDidZoom(_ scrollView: UIScrollView) {
print("\(logClassName) TEST -> scrollView did zoom \(scrollView.zoomScale)")
expandHorizontally(withScale: scrollView.zoomScale)
//scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x, y: 0)
//scrollView.contentSize = CGSize(width: scrollView.contentSize.width, height: scrollView.frame.height)
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return waveView
}
private func expandHorizontally(withScale scale:CGFloat){
let scaledWidth = currentWaveViewWidth * scale
print("\(logClassName) TEST -> scaledWidth = \(scaledWidth)")
updateWidthConstraintValue(scaledWidth)
// Adjust content size and content offset
scrollView.contentSize = CGSize(width: waveViewWidthConstraint.constant,
height: 0);
scrollView.contentOffset = CGPoint(x: scrollView.contentOffset.x,
y: scrollView.contentOffset.y);
}
Переменные пользовательского интерфейса объявлены так:
lazy private (set) var scrollView:UIScrollView = {
let rtView = UIScrollView()
rtView.translatesAutoresizingMaskIntoConstraints = false
rtView.backgroundColor = .clear
rtView.bounces = false
rtView.bouncesZoom = false
rtView.minimumZoomScale = 1
rtView.maximumZoomScale = 3
rtView.delegate = self
return rtView
}()
private (set) lazy var waveView:UIView = {
let rtView = UIView()
rtView.translatesAutoresizingMaskIntoConstraints = false
rtView.backgroundColor = .clear
rtView.addGestureRecognizer(UITapGestureRecognizer(target: self,
action: #selector(waveViewDidTouch)))
return rtView
}()
private (set) var waveViewWidthConstraint = NSLayoutConstraint()
private (set) lazy var soundWaveImageView:UIImageView = {
let rtView = UIImageView()
rtView.translatesAutoresizingMaskIntoConstraints = false
return rtView
}()
private (set) lazy var timeMarkerView:UIView = {
let rtView = UIView()
rtView.translatesAutoresizingMaskIntoConstraints = false
rtView.backgroundColor = UIColor.AppColors.defaultTint
return rtView
}()
private var timerMarkerViewLeadingContraint = NSLayoutConstraint()
private (set) lazy var leftMarkerView:MarkerView = {
let rtView = MarkerView(title: AppHelper.printLocalized(withKey: "messages.start", targetSpecific: false), markerDirection: .right)
rtView.translatesAutoresizingMaskIntoConstraints = false
rtView.delegate = self
return rtView
}()
private var leftMarkerViewLeadingConstraint = NSLayoutConstraint()
private (set) lazy var rightMarkerView:MarkerView = {
let rtView = MarkerView(title: AppHelper.printLocalized(withKey: "messages.end", targetSpecific: false), markerDirection: .left)
rtView.translatesAutoresizingMaskIntoConstraints = false
rtView.delegate = self
return rtView
}()
private var rightMarkerViewLeadingConstraint = NSLayoutConstraint()
Я попытался поместить всю необходимую информацию, поскольку это большой класс.