Как настроить размер содержимого UIScrollView динамически
У меня вопрос о UIScrollview
.
История: у меня есть UIView
именем ChartsView, который я повторно рисую сам, переопределив метод drawRect()
. Содержимое чертежа генерировалось динамически. Поэтому я не знаю его размер до времени исполнения. Вопрос в том, как / где можно установить динамический размер содержимого супервизора (scrollView)? Любая идея об этом?
- (void)viewDidLoad { [super viewDidLoad]; // not this way. it's fixed size..... ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; self.scrollView.contentSize = chartsView.frame.size; [self.scrollView addSubview:chartsView]; }
- UITableView, прокрутите вниз до перезагрузки?
- как зарегистрировать приложение, чтобы открыть файл pdf в моем приложении в ipad
- программный доступ к кнопкам громкости iPhone
- Что делает флаг компоновщика -all_load?
- Пользовательский пузырь выноски MKPinAnnotation похож на пузырь по умолчанию
- Как я смогу удалить объекты из NSMutableArray?
- Нажмите ViewController справа налево с помощью UINavigationController
- Как я могу программно приостановить NSTimer?
- Как обнаружить паузу во вводе для UISearchBar / UITextField?
- Содержимое HTML соответствует UIWebview без масштабирования
- Опубликовать фотографию на стене пользователя, используя Facebook iOS SDK
- Как найти причину ошибки «double free» malloc?
- Легкий способ убрать клавиатуру?
Еще один простой способ
- (void)viewDidLoad { float sizeOfContent = 0; UIView *lLast = [scrollView.subviews lastObject]; NSInteger wd = lLast.frame.origin.y; NSInteger ht = lLast.frame.size.height; sizeOfContent = wd+ht; scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, sizeOfContent); }
быстрый (2.0)
@IBOutlet weak var btnLatestButton: UIButton! override func viewDidLoad() { super.viewDidLoad() let height = btnLatestButton.frame.size.height let pos = btnLatestButton.frame.origin.y let sizeOfContent = height + pos + 10 scrollview.contentSize.height = sizeOfContent }
Выше, конечно, когда у вас только фиксированное количество просмотров на вашем прокрутке. Метод IOS Rocks доступен, но мне нехорошо, я создал больше пространства, чем мне было нужно.
let lastView : UIView! = scrollview.subviews.last let height = lastView.frame.size.height let pos = lastView.frame.origin.y let sizeOfContent = height + pos + 10 scrollview.contentSize.height = sizeOfContent
Благодаря IOS Rocks и CularBytes для потенциальных клиентов. Я нашел две проблемы (для меня) с вышеупомянутыми решениями:
- У меня всегда есть контейнер UIView как единственный дочерний элемент моего UIScrollView, поэтому мне пришлось обновить способ поиска последнего вида в этом дочернем UIView (см. Ниже)
- Я компенсирую свой контент в UIScrollView и, как таковой, должен вычислить абсолютную позицию этого последнего UIView (так, относительно windows, а не родительского представления)
Также я использую autolayout для привязки сторон UIScrollView, поэтому мне не нужно беспокоиться о ширине (как и CularBytes).
Вот что я придумал и работает (в Swift 3.0):
func setScrollViewContentSize() { var height: CGFloat let lastView = self.myScrollView.subviews[0].subviews.last! print(lastView.debugDescription) // should be what you expect let lastViewYPos = lastView.convert(lastView.frame.origin, to: nil).y // this is absolute positioning, not relative let lastViewHeight = lastView.frame.size.height // sanity check on these print(lastViewYPos) print(lastViewHeight) height = lastViewYPos + lastViewHeight print("setting scroll height: \(height)") myScrollView.contentSize.height = height }
Я называю это в своем viewDidAppear()
.
На 100% гарантировано, что последний объект в массиве scrollView.subviews вернет самый высокий объект y-origin в вашем представлении прокрутки. Массив subviews упорядочивается Z-Index (т. Е. Последний объект в массиве subviews будет объектом, уложенным выше и будет самым верхним subview в подзонах представления прокрутки. Вместо этого более точно использовать базовую функцию сортировки для итерации по подзонам и получения объекта с наивысшим y-началом.
Вот базовая функция в swift 3, которая может сделать это:
func calculateContentSize(scrollView: UIScrollView) -> CGSize { var topPoint = CGFloat() var height = CGFloat() for subview in scrollView.subviews { if subview.frame.origin.y > topPoint { topPoint = subview.frame.origin.y height = subview.frame.size.height } } return CGSize(width: scrollView.frame.size.width, height: height + topPoint) }
Использование (в viewDidLayoutSubviews или при каждом обновлении размера содержимого):
scrollView.contentSize = calculateContentSize(scrollView: scrollView)
ОБНОВЛЕНИЕ SWIFT 4
Вот более часовая версия в быстрой версии 4
extension UIScrollView { func updateContentView() { contentSize.height = subviews.sorted(by: { $0.frame.maxY < $1.frame.maxY }).last?.frame.maxY ?? contentSize.height } }
Применение:
myScrollView.updateContentView()
попробуй это
- (void)viewDidLoad { [super viewDidLoad]; // not this way. it's fixed size..... ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; self.scrollView.contentSize = chartsView.frame.size; [self.scrollView setNeedsDisplay]; [self.scrollView addSubview:chartsView]; }
Попробуй это –
- (void)viewDidLoad { [super viewDidLoad]; // not this way. it's fixed size..... ChartsView *chartsView = [[ChartsView alloc]initWithFrame:CGRectMake(0, 0, 320, 800)]; //self.scrollView.contentSize = chartsView.frame.size; [self.scrollView setContentSize:CGSizeMake(chartsView.frame.size.width, chartsView.frame.size.height)]; [self.scrollView addSubview:chartsView]; }
Это расширение, написанное на Swift 3
extension UIScrollView { func updateContentViewSize() { var newHeight: CGFloat = 0 for view in subviews { let ref = view.frame.origin.y + view.frame.height if ref > newHeight { newHeight = ref } } let oldSize = contentSize let newSize = CGSize(width: oldSize.width, height: newHeight + 100) contentSize = newSize } }