ios - how - swift title text color




Пользовательская кнопка возврата iOS 7 (8)

Я хочу использовать пользовательскую кнопку возврата. в iOS 6 все идеально, но iOS 7 странно.

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:[[UIImage imageNamed:@"back_button_normal"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12.0, 0, 12.0)] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

во-первых, у него нет стрелки iOS 7 и никакого фонового изображения.

(Русский язык)

затем, если вы нажмете кнопку, появится фоновое изображение. Также у меня было фоновое изображение, настроенное для состояния UIControlStateHighlighted и когда вы удерживаете кнопку нажатой, появляется выделенное изображение. После того, как любая кнопка назад нажата, все кнопки назад имеют фоновое изображение.

НО! Если вы представляете контроллер модального просмотра, отпустите его, а затем нажмите любой контроллер вида - на каждой задней кнопке появится стрелка iOS 7 .

Я использую DP5. Это ошибка UIKit?

PS Также я попытался создать кнопку возврата вручную, используя UIBarButtonItem , установить для него фоновое изображение, затем self.navigationItem.backBarButtonItem = barButtonItem; Не помогло. Затем я попытался установить фоновое изображение в отключенное состояние и изменить включенное свойство элемента панели бара, тоже не помогло.


Используя Swift, вы можете просто добавить расширение:

extension UIViewController: UIGestureRecognizerDelegate {
    func popBack() {
        self.navigationController?.popViewControllerAnimated(true)
    }

    func enableCustomBackButtom() {
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "icon-back"), style: UIBarButtonItemStyle.Plain, target: self, action:"popBack")

        self.navigationController?.interactivePopGestureRecognizer.delegate = self
    }
}

И в вашем UIViewController используйте вот так:

self.enableCustomBackButtom()

Как я могу сказать, пользовательское фоновое изображение, не появившееся первоначально, не было исправлено в iOS7 GM или final. Я вижу ту же проблему. Кажется, это ошибка Apple; частный вид Apple использует просто не получает вызов setNeedsDisplay, когда он нуждается в нем при первоначальном отображении. Выполнение чего-либо, что вызывает этот вызов, должно исправлять его - например, нажатие на него (что, скорее всего, изменяет внутреннее состояние, так что он вызывает setNeedsDisplay сам по себе), или привносит модальный уровень (что, вероятно, заставляет повторно отобразить всю иерархию представлений на следующем viewWillAppear: call).

Использование leftBarItems также может работать, но это может вызвать множество проблем с обслуживанием существующего кода (некоторые экраны могут иметь свои собственные элементы слева, ожидая, что, когда они вернутся к нулю, они восстанавливают исходный задний элемент, например).

Как уже упоминалось, в идеале вы сможете перейти на безграничный внешний вид на iOS7, а это значит, что ошибка на самом деле не очевидна (поскольку фоновое изображение отсутствует). Однако для некоторых ситуаций перехода iOS6 / iOS7 это может быть сложно (большое количество экранов и / или необходимость поддерживать более старые версии iOS на некоторое время и слишком сложно реализовать два взгляда, и он не выглядит хорошо без полей без других изменения). Если это так, следующий патч должен работать:

#import <objc/runtime.h>

@implementation UINavigationBar (BackButtonDisplayFix)

+ (void)load
{
    if ([UIDevice currentDevice].systemVersion.intValue >= 7)
    {
        /*
         * We first try to simply add an override version of didAddSubview: to the class.  If it
         * fails, that means that the class already has its own override implementation of the method
         * (which we are expecting in this case), so use a method-swap version instead.
         */
        Method didAddMethod = class_getInstanceMethod(self, @selector(_displaybugfixsuper_didAddSubview:));
        if (!class_addMethod(self, @selector(didAddSubview:),
                             method_getImplementation(didAddMethod),
                             method_getTypeEncoding(didAddMethod)))
        {
            Method existMethod = class_getInstanceMethod(self, @selector(didAddSubview:));
            Method replacement = class_getInstanceMethod(self, @selector(_displaybugfix_didAddSubview:));
            method_exchangeImplementations(existMethod, replacement);
        }
    }
}

- (void)_displaybugfixsuper_didAddSubview:(UIView *)subview
{
    [super didAddSubview:subview];
    [subview setNeedsDisplay];
}

- (void)_displaybugfix_didAddSubview:(UIView *)subview
{
    [self _displaybugfix_didAddSubview:subview]; // calls the existing method
    [subview setNeedsDisplay];
}

@end

Примечание: UINavigationBar в настоящее время имеет переопределение метода, о котором идет речь, поэтому я ожидаю, что будет использоваться стиль method_exchangeImplementations. Я просто добавил другой материал для безопасности, если Apple изменит свой код. Мы можем пойти без границ, но я нашел, что этот подход работал как опция (до более тщательного повышения UI), по крайней мере.

Примечание. Эта ошибка исправлена ​​в iOS 7.1. Таким образом, исправление может быть обусловлено только установкой методов при запуске> = 7.0 и <7.1.


Мое решение состояло в том, чтобы написать категорию в UINavigationItem. Это для iOS7.

- (void)mdSetCustomBackButton:(UINavigationController *)navigationController
{
    MDBackButton *backButton = [[MDBackButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 44.0, 44.0) navigationController:navigationController];
    [backButton addTarget:self action:@selector(popBack:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    [self setLeftBarButtonItem:barButtonItem];
    [navigationController.interactivePopGestureRecognizer setDelegate:(id<UIGestureRecognizerDelegate>)self];
}

- (void)popBack:(MDBackButton *)sender
{
    [sender.navigationController popViewControllerAnimated:YES];
}

И подкласс UIButton, чтобы добавить свойство UINavigationController (чтобы поп и установить салфетки обратно делегата).

@property (nonatomic, weak) UINavigationController *navigationController;

@implementation MDBackButton

- (id)initWithFrame:(CGRect)frame navigationController:(UINavigationController *)navigationController
{
    self = [super initWithFrame:frame];
    if(self){
        _navigationController = navigationController;
        [self setImage:[UIImage imageNamed:@"back_button"] forState:UIControlStateNormal];
    }
    return self;
}

Пользовательское фоновое изображение, не появившееся при первом нажатии, было исправлено в iOS 7 GM.

Чтобы скрыть стандартный индикатор назад, используйте этот код:

if ([UINavigationBar instancesRespondToSelector:@selector(setBackIndicatorImage:)]) { // iOS 7
    [navigationBarAppearance setBackIndicatorImage:[UIImage imageNamed:@"transparent_1px"]];
    [navigationBarAppearance setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"transparent_1px"]];
}

Это не ошибка, как выглядит Back button в iOS 7. Например:

Вероятно, вы должны использовать новую концепцию для своего приложения, а не устанавливать фоновое изображение для кнопки «Назад» в iOS 7.

Если вы все еще хотите, чтобы кнопка возврата была такой же, как и в iOS6, вы должны, вероятно, создать эти кнопки назад вручную:

- (void)loadView
{
    [super loadView];

    UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(0, 0, 60.0f, 30.0f)];
    UIImage *backImage = [[UIImage imageNamed:@"back_button_normal.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12.0f, 0, 12.0f)];
    [backButton setBackgroundImage:backImage  forState:UIControlStateNormal];
    [backButton setTitle:@"Back" forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(popBack) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    self.navigationItem.leftBarButtonItem = backButtonItem;
}

-(void) popBack {
  [self.navigationController popViewControllerAnimated:YES];
}

Изменить : не прерывать жестов разворота ( вот источник)

self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;

Это работа для меня:

- (void)setCustomNavigationBackButton
{    
  self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];

  UIImage *myIcon = [self imageWithImage:[UIImage imageNamed:@"backbutton.png"] scaledToSize:CGSizeMake(20, 20)];

  self.navigationController.navigationBar.backIndicatorImage = myIcon;
  self.navigationController.navigationBar.backIndicatorTransitionMaskImage = myIcon;
}

- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize 
{
  //UIGraphicsBeginImageContext(newSize);
  // In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
  // Pass 1.0 to force exact pixel size.
  UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
  [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
  UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return newImage;
}

Кроме того, пользовательский шрифт с пользовательским цветом:

//self.navigationController.navigationBar.tintColor = [UIColor whiteColor];

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:
 @{NSForegroundColorAttributeName:[UIColor whiteColor],
   NSFontAttributeName:[UIFont fontWithName:@"Signika-Bold" size:20]}

forState:UIControlStateNormal];

Ссылка: https://.com/a/2658801/1371949


Я просто сделал это с тем же поведением, что и в iOS6 (обратите внимание, что navigationBar является UINavigationBar), убедитесь, что navigationBar имеет topItem

UINavigationItem *topItemNavigation = [navigationBar topItem];

UIBarButtonItem *barButtonTopItemNavigation = [[UIBarButtonItem alloc] initWithTitle:topItemNavigation.title style:UIBarButtonItemStyleBordered target:nil action:nil];

[barButtonTopItemNavigation setBackButtonBackgroundImage:YOUR_IMAGE_BACKGROUND forState:UIControlStateNormal barMetrics:UIBarMetricsDefault ];
            [topItemNavigation setBackBarButtonItem: barButtonTopItemNavigation];
        }

Добавить кнопку в качестве элемента навигации в ios7, как показано ниже.

 UIButton *btnAdd = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 60, 30)];

        [btnAdd setContentMode:UIViewContentModeScaleAspectFit];

        [btnAdd setBackgroundImage:[UIImage imageNamed:@"back.png"] forState:UIControlStateNormal];

        [btnAdd addTarget:self action:@selector(backButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

        UIBarButtonItem *btnAdd = [[UIBarButtonItem alloc] initWithCustomView:imView];

        self.navigationItem.rightBarButtonItem = btnAdd;




xcode5