Skip to content

Commit

Permalink
fix: ios copy paste (#135)
Browse files Browse the repository at this point in the history
* fix(MD-3806): copy paste

* fix(MD-3812): fix conditional colors and image downloads

* fix(MD-3769): capture first column
fix(MD-3813): fix mini charts

* fix(MD-3834): wandering scrollbar

* fix(MD-3797): show images and links

* fix(MD-3808): hide selection band on scroll

* fix(MD-3832): ignore data with different columns

Co-authored-by: Vittorio Cellucci <vel@qlik.com>
  • Loading branch information
vcellu and vcellu committed Nov 13, 2022
1 parent c420493 commit a8195f3
Show file tree
Hide file tree
Showing 22 changed files with 381 additions and 166 deletions.
2 changes: 1 addition & 1 deletion ios/ColumnResizerView.swift
Expand Up @@ -127,7 +127,7 @@ class ColumnResizerView: UIView {
}
data.childCollectionView?.collectionViewLayout.invalidateLayout()

containerView?.multiColumnTable?.dataCollectionView?.childCollectionView?.showsVerticalScrollIndicator = false

containerView?.updateVScrollPos()
updateHeader(translation)
updateTotals(translation)
Expand Down
3 changes: 2 additions & 1 deletion ios/ColumnWidths.swift
Expand Up @@ -19,7 +19,8 @@ class ColumnWidths {
func count() -> Int {
return columnWidths.count
}



func loadDefaultWidths(_ frame: CGRect, columnCount: Int, dataRows: [DataRow], dataCols: [DataColumn]) {
if !loadFromStorage(columnCount) {
let defaultWidth = frame.width / Double(columnCount)
Expand Down
27 changes: 19 additions & 8 deletions ios/ContainerView.swift
Expand Up @@ -26,6 +26,7 @@ class ContainerView: UIView {
var maxHeaderLineCount = 1
var maxTotalsLineCount = 1
var maxCollectionViewsLineCount = 1
var needsInvalidation = false
weak var firstColumnTable: TableView?
weak var multiColumnTable: TableView?

Expand Down Expand Up @@ -92,11 +93,15 @@ class ContainerView: UIView {
do {
let json = try JSONSerialization.data(withJSONObject: cols)
let decodedCols = try JSONDecoder().decode(Cols.self, from: json)
if(dataColumns != nil && decodedCols.header?.count != dataColumns?.count) {
self.needsInvalidation = true
return
}
dataColumns = decodedCols.header
totals = decodedCols.totals
guard let firstTable = self.firstColumnTable else { return }
guard let multiTable = self.multiColumnTable else { return }

if let firstTotals = firstTable.totalView, let multiTotals = multiTable.totalView {
firstTotals.resetTotals(totals)
multiTotals.resetTotals(totals)
Expand All @@ -120,6 +125,9 @@ class ContainerView: UIView {
NotificationCenter.default.post(name: Notification.Name.onClearSelectionBand, object: nil)
let json = try JSONSerialization.data(withJSONObject: rows)
let decodedRows = try JSONDecoder().decode(RowsObject.self, from: json)
if(dataRows != nil && dataRows?[0].cells.count != decodedRows.rows?[0].cells.count) {
return
}
if dataRows == nil || decodedRows.reset == true {
self.dataRows = decodedRows.rows
if self.dataRows != nil {
Expand Down Expand Up @@ -218,18 +226,18 @@ class ContainerView: UIView {
self.horizontalScrollView?.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
self.firstColumnTable?.dataCollectionView?.postSignalVisibleRows(scrollsToTop: true)
self.testTruncation()
self.updateVScrollPos()
}
} else {
guard let firstColumnTable = self.firstColumnTable else { return }
guard let multiColumnTable = self.multiColumnTable else { return }
hScrollViewDelegate.captureFirstColumnWidth()
firstColumnTable.resizeCells()
multiColumnTable.resizeCells()
testTruncation()
DispatchQueue.main.async {
if let horizontalScrollView = self.horizontalScrollView {
horizontalScrollView.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
self.firstColumnTable?.dataCollectionView?.postSignalVisibleRows(scrollsToTop: true)
}
self.testTruncation()
self.firstColumnTable?.dataCollectionView?.postSignalVisibleRows(scrollsToTop: true)
self.updateVScrollPos()
}
}
}
Expand Down Expand Up @@ -317,9 +325,12 @@ class ContainerView: UIView {
func updateVScrollPos() {
let totalWidth = columnWidths.getTotalWidth()
let rawX = firstColumnTable?.horizontalScrolLView?.contentOffset.x ?? 0.0
let right = max(abs(self.frame.width - totalWidth) - rawX, 0)
var right = max(abs(self.frame.width - totalWidth) - rawX, 0)
if(totalWidth < frame.width) {
right = 2.0
}
firstColumnTable?.dataCollectionView?.childCollectionView?.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: right)
multiColumnTable?.dataCollectionView?.childCollectionView?.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: right)
multiColumnTable?.dataCollectionView?.childCollectionView?.showsVerticalScrollIndicator = true
}

}
70 changes: 36 additions & 34 deletions ios/DataCollectionView.swift
Expand Up @@ -11,7 +11,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
enum DataCollectionViewError: Error {
case noCellForIdentifier
}

var stylingInfo = [StylingInfo]()
var dataColumns: [DataColumn]?
var dataRows: [DataRow]?
Expand All @@ -36,7 +36,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
weak var headerView: HeaderView?
weak var hScrollView: UIScrollView?
weak var selectionBand: SelectionBand?

init(frame: CGRect, withRows rows: [DataRow],
andColumns cols: [DataColumn],
theme: TableTheme,
Expand All @@ -60,20 +60,19 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
fitToFrame()
createSelectionBands()
}

fileprivate func fitToFrame() {
guard let childCollectionView = childCollectionView else {
return
}
childCollectionView.translatesAutoresizingMaskIntoConstraints = false
childCollectionView.fitToView(self)
childCollectionView.showsHorizontalScrollIndicator = false
childCollectionView.showsVerticalScrollIndicator = false
}

fileprivate func createSelectionBands() {
guard let childCollectionView = childCollectionView else { return }

let selectionBand = SelectionBand(frame: self.frame)
childCollectionView.addSubview(selectionBand)
selectionBand.translatesAutoresizingMaskIntoConstraints = false
Expand All @@ -83,25 +82,25 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
self.selectionBand = selectionBand
}

required init?(coder: NSCoder) {
super.init(coder: coder)
}

func scrollToTop() {
if let childCollectionView = childCollectionView {
childCollectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .top, animated: true)
}
}

func updateSize(_ translation: CGPoint, withColumn index: Int) -> Bool {
if !updateCell(translation, withColum: index) {
return false
}

return true
}

func updateCell(_ translation: CGPoint, withColum index: Int) -> Bool {
if let cv = self.childCollectionView {
let visibleCells = cv.subviews
Expand All @@ -115,7 +114,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
return true
}

func resizeCells() {
guard let columnWidths = columnWidths else { return }
if let cv = self.childCollectionView {
Expand All @@ -128,22 +127,25 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
childCollectionView?.collectionViewLayout.invalidateLayout()
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
syncScrolling()
}

func syncScrolling() {
if let coupled = coupled, let childCollectionView = childCollectionView {
if let slaveChild = coupled.childCollectionView {
coupled.selectionBand?.clearRect()
if let child = coupled.childCollectionView {
let y = childCollectionView.contentOffset.y
slaveChild.contentOffset.y = y
child.contentOffset.y = y
}
selectionBand?.clearRect()
}
signalVisibleRows()
}

func signalVisibleRows() {


func signalVisibleRows() {
if let childCollectionView = childCollectionView {
var min = Int.max
var max = Int.min
Expand All @@ -160,7 +162,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
}
}

let arrayOfVisibleItems = childCollectionView.indexPathsForVisibleItems.sorted()
let firstItem = arrayOfVisibleItems.first
let lastItem = arrayOfVisibleItems.last
Expand All @@ -169,15 +171,15 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
}
}

func setData(columns: [DataColumn], withRows rows: [DataRow]) {
dataColumns = columns
dataRows = rows
setupDataCols()
let flowLayout = UICollectionViewFlowLayout()
let uiCollectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
uiCollectionView.translatesAutoresizingMaskIntoConstraints = false

uiCollectionView.register(DataCellView.self, forCellWithReuseIdentifier: reuseIdentifier)
uiCollectionView.delegate = self
uiCollectionView.dataSource = self
Expand All @@ -186,7 +188,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
childCollectionView = uiCollectionView
addSubview(uiCollectionView)
}

fileprivate func setupDataCols() {
guard let dataColumns = dataColumns else {
return
Expand All @@ -208,7 +210,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
}
}

func appendData(rows: [DataRow]) {
DispatchQueue.main.async {
self.dataRows = rows
Expand All @@ -231,7 +233,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
})
}
}

// MARK: collectionview
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// swiftlint:disable:next force_cast
Expand All @@ -256,37 +258,37 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
cellStyle: self.cellStyle,
withRange: dataRange)
}

return cell
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataRows?.count ?? 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = self.bounds.width
let numberOfLines = max(cellStyle?.cellContentStyle?.rowHeight ?? maxRowLineCount, maxRowLineCount)
let lineHeight = cellStyle?.lineHeight ?? TableTheme.CellContentHeight
let height = Double(numberOfLines) * lineHeight
return CGSize(width: width, height: height + (PaddedLabel.PaddingSize * 2.0))
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.5
}

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
let rowCount = dataRows!.count
if indexPath.row == rowCount - 50 && !loading {
loadMoreData()
}
}

func loadMoreData() {
DispatchQueue.global(qos: .userInitiated).async {
if let requestOnEndReached = self.onEndReached, let size = self.dataSize, let rows = self.dataRows {
Expand All @@ -297,7 +299,7 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
}
}

func getMaxLineCount() -> Int {
guard let childCollectionView = childCollectionView else { return maxRowLineCount }
var lines = 0
Expand All @@ -308,10 +310,10 @@ class DataCollectionView: UIView, UICollectionViewDataSource, UICollectionViewDe
}
return lines
}

func setMaxLineCount(_ lines: Int) {
maxRowLineCount = lines
childCollectionView?.collectionViewLayout.invalidateLayout()
}

}
4 changes: 2 additions & 2 deletions ios/Extensions.swift
Expand Up @@ -9,7 +9,7 @@ import Foundation

extension UIView {
func addBottomShadow() {
layer.shadowRadius = 3
layer.shadowRadius = 2
layer.shadowOpacity = 0.25
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 1)
Expand All @@ -24,7 +24,7 @@ extension UIView {
func addTopShadow() {
self.clipsToBounds = false
layer.shadowRadius = 2
layer.shadowOpacity = 0.15
layer.shadowOpacity = 0.25
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 1)
layer.shadowPath = UIBezierPath(rect: CGRect(x: 0,
Expand Down
19 changes: 10 additions & 9 deletions ios/HorizontalScrolViewDelegate.swift
Expand Up @@ -13,6 +13,7 @@ class HorizontalScrollViewDelegate: NSObject, UIScrollViewDelegate {
weak var headersView: UIView?
weak var columnWidths: ColumnWidths?
weak var grabber: ColumnResizerView?
weak var containerView: ContainerView?
var translateion = CGPoint.zero
var width = 0.0
var freezeFirstCol = false
Expand All @@ -27,27 +28,27 @@ class HorizontalScrollViewDelegate: NSObject, UIScrollViewDelegate {
guard let columnWidths = self.columnWidths else { return }
guard let tableView = self.tableView else { return }
guard let grabber = self.grabber else { return }
guard let containerView = self.containerView else { return }

let totalWidth = columnWidths.getTotalWidth()
let shadowOffsetX = clampScrollPos(Float(scrollView.contentOffset.x))
let rawX = scrollView.contentOffset.x
let right = max(abs(scrollView.frame.width - totalWidth) - rawX, 0)



var right = max(abs(scrollView.frame.width - totalWidth) - rawX, 0)
if (totalWidth < Double(containerView.frame.width)) {
right = 2
}

if(rawX >= 0) {
multiColumnTable?.dataCollectionView?.childCollectionView?.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: right)
tableView.dataCollectionView?.childCollectionView?.scrollIndicatorInsets.right = right
multiColumnTable?.dataCollectionView?.childCollectionView?.scrollIndicatorInsets.right = right
}
if (freezeFirstCol) {
if rawX <= 0 {
multiColumnTable?.dataCollectionView?.childCollectionView?.showsVerticalScrollIndicator = false
let x = width - rawX
let translation = CGPoint(x: x, y: 0)
columnWidths.columnWidths[0] = x
tableView.setWidth(x)
_ = tableView.dataCollectionView?.updateSize(translation, withColumn: 0)
tableView.dataCollectionView?.childCollectionView?.collectionViewLayout.invalidateLayout()
grabber.setPosition(x)
containerView.testTruncation()
}

let offset = shadowOffsetX/100.0
Expand Down

0 comments on commit a8195f3

Please sign in to comment.