Peut-être un simple!
Est-ce que quelqu'un sait comment afficher en permanence la barre de défilement d'un UIScrollView?
Il s’affiche lorsque l’utilisateur défile pour qu’il puisse voir dans quelle position de la vue de défilement il se trouve.
MAIS je voudrais le montrer constamment parce qu'il n'est pas immédiatement évident pour l'utilisateur que le défilement est disponible
Tout conseil serait hautement apprécié.
Non, vous ne pouvez pas toujours les afficher, mais vous pouvez les faire clignoter temporairement.
[myScrollView flashScrollIndicators];
Ce sont des indicateurs de défilement, pas des barres de défilement. Vous ne pouvez pas les utiliser pour faire défiler.
ma solution pour afficher les indicateurs de défilement tout le temps
#define noDisableVerticalScrollTag 836913
#define noDisableHorizontalScrollTag 836914
@implementation UIImageView (ForScrollView)
- (void) setAlpha:(float)alpha {
if (self.superview.tag == noDisableVerticalScrollTag) {
if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) {
if (self.frame.size.width < 10 && self.frame.size.height > self.frame.size.width) {
UIScrollView *sc = (UIScrollView*)self.superview;
if (sc.frame.size.height < sc.contentSize.height) {
return;
}
}
}
}
if (self.superview.tag == noDisableHorizontalScrollTag) {
if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) {
if (self.frame.size.height < 10 && self.frame.size.height < self.frame.size.width) {
UIScrollView *sc = (UIScrollView*)self.superview;
if (sc.frame.size.width < sc.contentSize.width) {
return;
}
}
}
}
[super setAlpha:alpha];
}
@end
UPDATE: cette solution pose des problèmes sur 64 bits. Pour plus de détails, regardez ici
Pour autant que je sache, ce n'est pas possible. Le seul appel d'API qui contrôle l'affichage de l'indicateur de défilement est showsVerticalScrollIndicator
et qui peut uniquement désactiver l'affichage de l'indicateur.
Vous pouvez flashScrollIndicators
lorsque la vue apparaît pour que l'utilisateur sache où ils se trouvent dans la vue de défilement.
Celui-ci a fonctionné pour moi:
#define noDisableVerticalScrollTag 836913
#define noDisableHorizontalScrollTag 836914
@implementation UIImageView (ForScrollView)
- (void) setAlpha:(float)alpha {
if (self.superview.tag == noDisableVerticalScrollTag) {
if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) {
if (self.frame.size.width < 10 && self.frame.size.height > self.frame.size.width) {
UIScrollView *sc = (UIScrollView*)self.superview;
if (sc.frame.size.height < sc.contentSize.height) {
return;
}
}
}
}
if (self.superview.tag == noDisableHorizontalScrollTag) {
if (alpha == 0 && self.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) {
if (self.frame.size.height < 10 && self.frame.size.height < self.frame.size.width) {
UIScrollView *sc = (UIScrollView*)self.superview;
if (sc.frame.size.width < sc.contentSize.width) {
return;
}
}
}
}
[super setAlpha:alpha];
}
@end
J'ai eu cet extrait d'ici: http://www.developers-life.com/scrollview-with-scrolls-indicators-which-are-shown-all-the-time.html
Je veux offrir ma solution. Je n'aime pas la variante la plus populaire avec category (le fait de surcharger les méthodes de la catégorie peut être la raison de l'indétermination de la méthode à appeler à l'exécution, car il existe deux méthodes avec le même sélecteur) . Et aussi je n'ai pas besoin d'utiliser des tags.
Ajoutez cette méthode à votre contrôleur de vue, où vous avez une vue de défilement (la propriété self.categoriesTableView
est une vue sous forme de tableau où je veux afficher les barres de défilement)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Do swizzling to turn scroll indicator always on
// Search correct subview with vertical scroll indicator image across tableView subviews
for (UIView * view in self.categoriesTableView.subviews) {
if ([view isKindOfClass:[UIImageView class]]) {
if (view.alpha == 0 && view.autoresizingMask == UIViewAutoresizingFlexibleLeftMargin) {
if (view.frame.size.width < 10 && view.frame.size.height > view.frame.size.width) {
if (self.categoriesTableView.frame.size.height < self.categoriesTableView.contentSize.height) {
// Swizzle class for found imageView, that should be scroll indicator
object_setClass(view, [AlwaysOpaqueImageView class]);
break;
}
}
}
}
}
// Search correct subview with horizontal scroll indicator image across tableView subviews
for (UIView * view in self.categoriesTableView.subviews) {
if ([view isKindOfClass:[UIImageView class]]) {
if (view.alpha == 0 && view.autoresizingMask == UIViewAutoresizingFlexibleTopMargin) {
if (view.frame.size.height < 10 && view.frame.size.height < view.frame.size.width) {
if (self.categoriesTableView.frame.size.width < self.categoriesTableView.contentSize.width) {
// Swizzle class for found imageView, that should be scroll indicator
object_setClass(view, [AlwaysOpaqueImageView class]);
break;
}
}
}
}
}
// Ask to flash indicator to turn it on
[self.categoriesTableView flashScrollIndicators];
}
Ajouter une nouvelle classe
@interface AlwaysOpaqueImageView : UIImageView
@end
@implementation AlwaysOpaqueImageView
- (void)setAlpha:(CGFloat)alpha {
[super setAlpha:1.0];
}
@end
L'indicateur de défilement (indicateur de défilement vertical dans le premier cycle for
et horizontal dans le deuxième cycle for
) sera toujours affiché à l'écran. Si vous n'avez besoin que d'un seul indicateur, ne laissez que ce cycle for
dans le code et supprimez-en un autre.
Barre de défilement qui fonctionne comme l’iOS intégré, mais vous pouvez jouer avec la couleur et la largeur.
-(void)persistantScrollBar
{
[persistantScrollBar removeFromSuperview];
[self.collectionView setNeedsLayout];
[self.collectionView layoutIfNeeded];
if (self.collectionView.contentSize.height > self.collectionView.frame.size.height + 10)
{
persistantScrollBar = [[UIView alloc] initWithFrame:(CGRectMake(self.view.frame.size.width - 10, self.collectionView.frame.Origin.y, 5, (self.collectionView.frame.size.height /self.collectionView.contentSize.height) * self.collectionView.frame.size.height))];
persistantScrollBar.backgroundColor = [UIColor colorWithRed:207/255.f green:207/255.f blue:207/255.f alpha:0.5f];
persistantScrollBar.layer.cornerRadius = persistantScrollBar.frame.size.width/2;
persistantScrollBar.layer.zPosition = 0;
[self.view addSubview:persistantScrollBar];
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect rect = persistantScrollBar.frame;
rect.Origin.y = scrollView.frame.Origin.y + (scrollView.contentOffset.y *(self.collectionView.frame.size.height/self.collectionView.contentSize.height));
rect.size.height = (self.collectionView.frame.size.height /self.collectionView.contentSize.height) * self.collectionView.frame.size.height;
if ( scrollView.contentOffset.y <= 0 )
{
rect.Origin.y = scrollView.frame.Origin.y;
rect.size.height = rect.size.height + (scrollView.contentOffset.y);
}
else if (scrollView.contentOffset.y + scrollView.frame.size.height >= scrollView.contentSize.height)
{
rect.size.height = rect.size.height - ((scrollView.contentOffset.y + scrollView.frame.size.height) - scrollView.contentSize.height);
rect.Origin.y = (self.collectionView.frame.Origin.y + self.collectionView.frame.size.height - 5) - rect.size.height;
}
persistantScrollBar.frame = rect;
}
iOS ne propose pas l'API. Mais si vous le souhaitez vraiment, vous pouvez ajouter votre indicateur personnalisé pour faire défiler la vue et le structurer vous-même, comme le fait la démo:
- (void) layoutSubviews { [super layoutSubviews]; if (self.showsVerticalScrollIndicatorAlways) { scroll_indicator_position (self, k_scroll_indicator_vertical); } if (self.showsHorizontalScrollIndicatorAlways) { scroll_indicator_position (self, k_scroll_indicator_horizontal); } }
Le lien est https://github.com/flexih/MazeScrollView
Swift 3
Vous pouvez accéder à la barre de défilement à l'aide de scrollView.subviews et modifier l'alpha comme indiqué ici. Ça marche pour moi.
extension UIScrollView {
override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for x in self.subviews {
x.alpha = 1.0
}
}
}
extension MyScrollViewDelegate : UIScrollViewDelegate {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
for x in scrollView.subviews {
x.alpha = 1.0
}
}
}
Pour les vues Web, où la première sous-vue est une vue de défilement, dans la dernière version du SDK, si une page HTML est plus longue que le cadre, aucune barre de défilement n'est affichée et si le contenu HTML s'aligne sur le cadre ou si vous disposez d'un espace. au bas du cadre, on dirait qu'il n'y a pas besoin de défilement et rien en dessous de la ligne. Dans ce cas, je pense que vous devriez absolument faire clignoter les barres de défilement dans la fenêtre du délégué.
- (void)webViewDidFinishLoad:(UIWebView *)webView;
méthode pour alerter l'utilisateur qu'il y a plus de choses "en dehors de la boîte".
NSArray *subViews = [[NSArray alloc] initWithArray:[webView subviews]] ;
UIScrollView *webScroller = (UIScrollView *)[subViews objectAtIndex:0] ;
Avec HTML, le contenu horizontal est automatiquement encapsulé. Vérifiez donc la hauteur de l'installateur Web.
if (webScroller.contentSize.height > webView.frame.size.height) {
[webScroller flashScrollIndicators];
}
Le flash est tellement court et survient pendant le chargement des vues, qu'il peut être négligé. Pour contourner ce problème, vous pouvez également secouer, faire rebondir, faire défiler ou redimensionner un peu le contenu via le commitAnimations générique d'UIView.