Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Refinements to the zooming system in the image previewer
Browse files Browse the repository at this point in the history
pablocarmu committed Oct 23, 2018
1 parent 9a0dd5c commit 7302ae8
Showing 3 changed files with 135 additions and 31 deletions.
4 changes: 4 additions & 0 deletions ownCloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@
6E4F1734217749910049A71B /* ImageDisplayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4F1733217749910049A71B /* ImageDisplayViewController.swift */; };
6E83C77E20A32C1B0066EC23 /* SettingsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E83C77D20A32C1B0066EC23 /* SettingsSection.swift */; };
6E83C78420A33C180066EC23 /* LAContext+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E83C78320A33C180066EC23 /* LAContext+Extension.swift */; };
6EA78B8F2179B55400A5216A /* ImageScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA78B8E2179B55400A5216A /* ImageScrollView.swift */; };
6EB8EDC52114358400C2BF44 /* folder-create.tvg in Resources */ = {isa = PBXBuildFile; fileRef = 6EB8EDBE2114358300C2BF44 /* folder-create.tvg */; };
75AC0B4AD332C8CC785FE349 /* Pods_ownCloudTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A56EA84D8AD331FFA604138B /* Pods_ownCloudTests.framework */; };
A45A8D98137C902524B84E6D /* EarlGrey.framework in EarlGrey Copy Files */ = {isa = PBXBuildFile; fileRef = D0D9C062DD1E85A838608B0F /* EarlGrey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
@@ -339,6 +340,7 @@
6E4F1733217749910049A71B /* ImageDisplayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDisplayViewController.swift; sourceTree = "<group>"; };
6E83C77D20A32C1B0066EC23 /* SettingsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSection.swift; sourceTree = "<group>"; };
6E83C78320A33C180066EC23 /* LAContext+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LAContext+Extension.swift"; sourceTree = "<group>"; };
6EA78B8E2179B55400A5216A /* ImageScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageScrollView.swift; sourceTree = "<group>"; };
6EB8EDBE2114358300C2BF44 /* folder-create.tvg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "folder-create.tvg"; path = "img/filetypes-tvg/folder-create.tvg"; sourceTree = SOURCE_ROOT; };
A56EA84D8AD331FFA604138B /* Pods_ownCloudTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ownCloudTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0D9C062DD1E85A838608B0F /* EarlGrey.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EarlGrey.framework; path = Pods/EarlGrey/EarlGrey/EarlGrey.framework; sourceTree = SOURCE_ROOT; };
@@ -841,6 +843,7 @@
DCF4F17E2051A0D000189B9A /* StaticTableViewRow.swift */,
DC018F8B20A1060A00135198 /* ProgressHUDViewController.swift */,
DC89C46220860B680044BCAE /* Progress */,
6EA78B8E2179B55400A5216A /* ImageScrollView.swift */,
);
path = "UI Elements";
sourceTree = "<group>";
@@ -1253,6 +1256,7 @@
DCE5E8B82080D8D9005F60CE /* OCItem+Extension.swift in Sources */,
232F7CAD2097140300EE22E4 /* UploadsSettingsSection.swift in Sources */,
597A404920AD59EF00B028B2 /* AppLockWindow.swift in Sources */,
6EA78B8F2179B55400A5216A /* ImageScrollView.swift in Sources */,
DC42244C207CAFBB0006A2A6 /* ThemeCollection.swift in Sources */,
DCFED9BA20809B8900A2D984 /* ThemeTVGResource.swift in Sources */,
DC3BE0DE2077CC14002A0AC0 /* ClientQueryViewController.swift in Sources */,
121 changes: 121 additions & 0 deletions ownCloud/UI Elements/ImageScrollView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
//
// ImageScrollView.swift
// ownCloud
//
// Created by Pablo Carrascal on 19/10/2018.
// Copyright © 2018 ownCloud GmbH. All rights reserved.
//

/*
* Copyright (C) 2018, ownCloud GmbH.
*
* This code is covered by the GNU Public License Version 3.
*
* For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/
* You should have received a copy of this license along with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.en.html>.
*
*/

import UIKit

class ImageScrollView: UIScrollView {

// MARK: - Constants
private let MAXIMUM_ZOOM_SCALE: CGFloat = 6.0

// MARK: - Instance Variables
private var imageView: UIImageView!

// MARK: - Init
override init(frame: CGRect) {
super.init(frame: frame)

showsVerticalScrollIndicator = false
showsHorizontalScrollIndicator = false
decelerationRate = UIScrollViewDecelerationRateFast
delegate = self
bounces = false
bouncesZoom = false
backgroundColor = .black
maximumZoomScale = MAXIMUM_ZOOM_SCALE
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
super.layoutSubviews()
centerImage()
}

// MARK: - Manage Scale
private func centerImage() {
let boundsSize: CGSize = bounds.size
var frameToCenter: CGRect = imageView?.frame ?? .zero

// center horizontally
if frameToCenter.size.width < boundsSize.width {
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width)/2
} else {
frameToCenter.origin.x = 0
}

// center vertically
if frameToCenter.size.height < boundsSize.height {
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height)/2
} else {
frameToCenter.origin.y = 0
}

imageView.frame = frameToCenter
}

private func setMinZoomScaleForCurrentBounds(_ size: CGSize? = nil) {
var boundsSize: CGSize
if size == nil {
boundsSize = self.bounds.size
} else {
boundsSize = size!
}
let imageSize = imageView.bounds.size

let xScale = boundsSize.width / imageSize.width
let yScale = boundsSize.height / imageSize.height
let minScale = min(xScale, yScale)

self.minimumZoomScale = minScale
}
}

// MARK: - Public API
extension ImageScrollView {

func updateScaleForRotation(size: CGSize) {
contentSize = size
setMinZoomScaleForCurrentBounds(size)
setZoomScale(zoomScale, animated: true)
zoomScale = minimumZoomScale
centerImage()
setNeedsLayout()
}

func display(image: UIImage) {
imageView?.removeFromSuperview()
imageView = UIImageView(image: image)
addSubview(imageView)
updateScaleForRotation(size: self.bounds.size)
}
}

// MARK: - ScrollViewDelegate
extension ImageScrollView: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}

func scrollViewDidZoom(_ scrollView: UIScrollView) {
centerImage()
}

}
41 changes: 10 additions & 31 deletions ownCloud/Viewer/ImageDisplayViewController.swift
Original file line number Diff line number Diff line change
@@ -11,44 +11,24 @@ import ownCloudSDK

class ImageDisplayViewController : DisplayViewController {

var scrollView: UIScrollView?
var scrollView: ImageScrollView?
var imageView: UIImageView?

override func renderSpecificView() {
scrollView = UIScrollView()

scrollView = ImageScrollView(frame: self.view.bounds)
scrollView?.translatesAutoresizingMaskIntoConstraints = false
scrollView?.maximumZoomScale = 6.0
scrollView?.bounces = false
scrollView?.bouncesZoom = false
scrollView?.delegate = self
self.view.addSubview(scrollView!)

NSLayoutConstraint.activate([
scrollView!.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor),
scrollView!.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor),
scrollView!.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
scrollView!.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)

scrollView!.leftAnchor.constraint(equalTo: view.leftAnchor),
scrollView!.rightAnchor.constraint(equalTo: view.rightAnchor),
scrollView!.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView!.topAnchor.constraint(equalTo: view.topAnchor)
])

imageView = UIImageView()
do {
let data = try Data(contentsOf: source)
let image = UIImage(data: data)
imageView?.image = image
imageView?.contentMode = .scaleAspectFit
imageView?.translatesAutoresizingMaskIntoConstraints = false
imageView?.backgroundColor = .black
scrollView!.addSubview(imageView!)
NSLayoutConstraint.activate([
imageView!.centerXAnchor.constraint(equalTo: scrollView!.centerXAnchor),
imageView!.centerYAnchor.constraint(equalTo: scrollView!.centerYAnchor),
imageView!.leftAnchor.constraint(equalTo: scrollView!.leftAnchor),
imageView!.rightAnchor.constraint(equalTo: scrollView!.rightAnchor),
imageView!.bottomAnchor.constraint(equalTo: scrollView!.bottomAnchor),
imageView!.topAnchor.constraint(equalTo: scrollView!.topAnchor)
])
scrollView?.display(image: image!)

} catch {
let alert = UIAlertController(with: "Error".localized, message: "Could not get the picture".localized, okLabel: "OK")
@@ -57,11 +37,10 @@ class ImageDisplayViewController : DisplayViewController {
}
}
}
}

extension ImageDisplayViewController: UIScrollViewDelegate {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
self.scrollView?.updateScaleForRotation(size: size)
}
}

0 comments on commit 7302ae8

Please sign in to comment.