Ответы пользователя по тегу Objective-C
  • Obj-C Как правильно работать с потоками?

    morozovdenis
    @morozovdenis
    в этом конкретном случае вам надо просто дизаблить кнопку

    - (IBAction)login:(UIButton *)sender {
            sender.enabled = NO;
    	AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    	NSDictionary *parameters = @{@"_login": @"bar", @"_pass" : @"123"};
    	[manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    	    NSLog(@"JSON: %@", responseObject);
                sender.enabled = YES;
    	} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    	    NSLog(@"Error: %@", error);
                sender.enabled = YES;
    	}];
    }


    в общем случае задача которую вы описываете на мой взгляд специфична для каждого проекта.

    если хотите запросы одного типа выполять последовательно, можете использовать например NSOperationQueue

    если хотите что-бы в один момент выполнялся только один запрос конкретного типа, то в любом случае заводить BOOL-флаг, можете написать обёртку над вашем методом выше которая сама будет рулить такие ситуации
    Ответ написан
    2 комментария
  • Как проиндексировать таблицу из массива объектов?

    morozovdenis
    @morozovdenis
    ...
        Customers *customers;
        NSMutableDictionary *dictionaryCustomers;
        NSArray *sortedKeys = nil;
    ...
            for (NSDictionary *dictionary in [responseData objectForKey:@"data_list"]) {
                customers = [[Customers alloc] init];
                
                for (NSString *key in [dictionary allKeys]) {
                    if ([customers respondsToSelector:NSSelectorFromString(key)]) {
                        [customers setValue:[dictionary objectForKey:key] forKey:key];
                    }
                }
                //например по имени индексируем
                NSString *fisrtSymbol = [[customers.name substringFromIndex:1] uppercaseString];
                if ([dictionaryCustomers.allKeys containsObject:fisrtSymbol] == NO)
                {
                       dictionaryCustomers[fisrtSymbol] = [NSMutableArray new];
                }
                [dictionaryCustomers[fisrtSymbol]  addObject:customers];
            }
            sortedKeys = [dictionaryCustomers.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
                return [obj1 compare:obj2];
            }]


    после этого
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
    return dictionaryCustomers.count;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
    return [dictionaryCustomers[sortedKeys[section]] count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    Customers *c = [dictionaryCustomers[sortedKeys[indexPath.section]] obkectAtIndex:indexPath.row];
    
    ...
    
    return cell;
    }
    
    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
    {
    return sortedKeys;
    }


    UPD:
    фильтр:
    @interface MyViewController ()
    @property NSMutableDictionary *dictionaryCustomers; // исходные которые были заполненны из responseData
    @property NSArray *sortedKeys; // исходные которые были заполненны из responseData
    
    @property NSDictionary *currentDictionaryCustomers; 
    @property NSArray *currentSortedKeys;
    
    @end
    
    @implemented MyViewController
    
    - (void)parseResponse:(id)responseData
    {
              // парсим ответ
              self.dictionaryCustomers = ...
              self.sortedKeys = ...
    
              self.currentDictionaryCustomers = self.dictionaryCustomers;
              self.currentSortedKeys = self.sortedKeys;
    }
    
    - (void)filterCustomers:(NSString *)sFilter
    {
              NSMutableDictionary *result = [NSMutableDictionary new];
                
                for (NSString *key in [self.dictionaryCustomers allKeys])
                {
                    for (Customers *customer in self.dictionaryCustomers[key])
                    {
                            if (<customer.company содержит sFilter>)
                            {
                                      if ([result.allKeys containsObject:key] == NO) result[key] = [NSmutableArray new];
                                      
                                      [result[key] addObject:customer];
                            }
                    }
                }
            self.currentDictionaryCustomers = result;
            self.currentSortedKeys = [result.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
                return [obj1 compare:obj2];
            }]
    
            [self.tableView reloadData];
    }
    
    // тут заполняем tableView из self.currentDictionaryCustomers и self.currentSortedKeys
    
    @end
    Ответ написан
  • Как изменить label при нажатии на кнопку в другом контроллере?

    morozovdenis
    @morozovdenis
    в WBCViewController подпишитесь на событие:
    -(void)viewDidLoad
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(needChangeLabel:) name:@"WBCAddWaterViewControllerChangeLabelNotification" object:nil];
    }
    
    - (void)needChangeLabel:(NSNotification *)n
    {
        NSLog(@"%@", n.userInfo);
    }
    
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:@"WBCAddWaterViewControllerChangeLabelNotification" object:nil];
    }


    в WBCAddWaterViewController отправляй событие:
    NSDictionary *userInfo = @{@"key1" : @"value1", @"key2" : @"value2"};
    [[NSNotificationCenter defaultCenter] postNotificationName:@"WBCAddWaterViewControllerChangeLabelNotification" object:nil userInfo:userInfo];
    Ответ написан
    Комментировать
  • Как послать уведомление о потере интернет-соединения через всё приложение?

    morozovdenis
    @morozovdenis
    по ссылке на github есть пример как отследить что пропал инет

    вот(я чуток изменил пример):
    @interface MyViewController ()
    
    @property (strong, nonatomic) SDReachability *reachability;
    
    @end
    
    
    @implementation MyViewController
    
    //...
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        [self monitorReachability];
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear];
        [self stopMonitorReachability];
    }
    
    - (void)monitorReachability
    {
        self.reachability = [SDReachability reachabilityWithTarget:self action:@selector(reachabilityChanged:)];
    }
    
    - (void)stopMonitorReachability
    {
        self.reachability = nil;
    }
    
    - (void)reachabilityChanged:(SDReachability *)reachability
    {
        switch (reachability.reachabilityStatus)
        {
            case SDNotReachable:
            {
                NSLog(@"Connection lost");
               UIAlertView* alert = [[UIAlertView alloc] initWithTitle:nil message:@"Connection lost" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
                [alert show];
                // тут делаеш с view всё что захочешь
                break;
            }
            case SDReachableViaWiFi:
                NSLog(@"Connected via WiFi");
                break;
    
            case SDReachableViaWWAN:
                NSLog(@"Connected via WWAN");
                break;
        }
    }
    
    @end

    так делаешь для каждого ViewController-а или можешь сделать это один раз в RootViewController:
    @interface MyRootViewController ()
    
    @property (strong, nonatomic) SDReachability *reachability;
    
    @end
    
    
    @implementation MyRootViewController
    
    //...
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        [self monitorReachability];
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear];
        [self stopMonitorReachability];
    }
    
    - (void)monitorReachability
    {
        self.reachability = [SDReachability reachabilityWithTarget:self action:@selector(reachabilityChanged:)];
    }
    
    - (void)stopMonitorReachability
    {
        self.reachability = nil;
    }
    
    - (void)reachabilityChanged:(SDReachability *)reachability
    {
        switch (reachability.reachabilityStatus)
        {
            case SDNotReachable:
            {
                NSLog(@"Connection lost");
               UIAlertView* alert = [[UIAlertView alloc] initWithTitle:nil message:@"Connection lost" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
                [alert show];
    
               [self.navigationController popToRootViewController]; // убираем все контроллеры из стека
               // тут модифицируешь self.view - например добавляеш на неё label "Connection Lost"
                break;
            }
            case SDReachableViaWiFi:
                NSLog(@"Connected via WiFi");
                break;
    
            case SDReachableViaWWAN:
                NSLog(@"Connected via WWAN");
                break;
        }
    }
    
    @end
    Ответ написан
  • Какая хорошая литература по Oblective-C?

    morozovdenis
    @morozovdenis
    я сам по началу не читал книжки по objective c, мне хватило пару статей для входа и потом что надо, то гуглил или смотрел документацию от apple

    попозже начинал читать две книги, но через некоторое кол-во страниц я понимал что ничего нового для себя не открывал и забросил:

    по objective-c надо читать книгу у которой апельсинка на обложке (www.ozon.ru/context/detail/id/21462201/) - такая выходит для каждой sdk, т.е. вам нужна такая же, но только для SDK 7.0/7.1

    по Core Data ещё есть хорошая: www.amazon.com/Pro-Core-Data-Second-Edition/dp/143...

    остальные книги которые я находил, посмотрел отзывы в сети и даже читать не начинал
    Ответ написан
  • Как исправить ошибку компиляции в Objective-C?

    morozovdenis
    @morozovdenis
    1. откройте xcode
    2. на панели что находится вверху экрана нажмите debug
    3. выбирите breakpoints
    4. нажмите create exception breakpoint

    таким образов вы увидите на какой строчке падает exception
    Ответ написан
    Комментировать
  • Как решить проблемы с получением размера UIView при отключении свойства translucent (ios7)?

    morozovdenis
    @morozovdenis
    1. не используйте UITableViewController - используйте UIViewController. по своему опыту скажу что лучше пусть под таблицей лежит ещё вьюха

    2. старый добрый autoresizing мне до сих пор хватает. что-то сложное лучше 3-мя строчками кода подписать

    |----------------------------|
    |                            |
    |                            |
    |                            |
    |        tableView           |
    |                            |
    |                            |
    |----------------------------|
    |----------------------------|
    |       ToolBarView.         |
    |----------------------------|


    у TableView пропишите autoresizingmask = (UIAutoresizingMaskFlixableHeight | UIAutoresizingMaskFlixableWidth) что соответствует проставлению всех красных маркеров в IB

    у ToolBarView пропишите autoresizingmask = (UIAutoresizingMaskFlixableWidth | UIAutoresizingMaskFlixableTopMargin) что соответствует проставлению следующих маркеров в IB: левый, правый, нижний и горизонтальная стрелка в право-лево
    Ответ написан
    1 комментарий
  • UITableView - как прикрутить комментарии к записям?

    morozovdenis
    @morozovdenis
    я бы сделал два типа ячейки с разным дизайном, в смысле ячейка первого типа представляет пользователя, а ячейка второго типа представляет комментарий. соответственно у них разные отступы, разная высота и т.д.

    если нужно что-бы ячейки раскрывались/закрывались и/или отображались только например 3 последних комментария, то по нажатию на кнопку "раскрыть комментарии" вызывать метод reloadData и пусть перестроит видимую часть таблицы

    UPD:
    Вам нужно в сториборде создать две разных ячейки и присвоить им в настройках два разных ReuseIdentifier-а(например UserCell для ячейки юзера и CommentCell для ячейки комментария). Потом прописать делегаты для кол-ва секций и кол-ва ячеек в каждой секции:
    #pragma mark - UITableViewDataSource
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return self.users.count;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.users[section].comments.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    	if (indexPath.row == 0)
    	{
    		UITableViewCell *cell = [[self tableViewAllCheckins] dequeueReusableCellWithIdentifier:@"UserCell"];
    		
    		NSDictionary *userInfo = self.users[indexPath.section];
    		
    		// заполнение ячейки User-а
    		
    		return cell;
    	}
    	else
    	{
    		CommentViewCell *commentCell = [[self tableViewAllCheckins] dequeueReusableCellWithIdentifier:@"CommentCell"];
    		
    		UserInfo *userInfo = self.users[indexPath.section];
    		
    		CommentInfo *comment = userInfo.comments[indexPath.row - 1]; // так как нулевая ячейка в секции принадлежит пользователю, а первая ячейка принадлежит нулевому комментарию, то надо сделать минус 1
    		
    		// заполнение ячейки Comment-а
    		
    		return commentCell;
    	}
    }
    Ответ написан
    8 комментариев
  • IOS - как осуществить игровую анимацию на заднем фоне?

    morozovdenis
    @morozovdenis
    навскинду два варианта сразу приходят на ум:

    1. реализовать свою view которая будет отображать список картинок по очереди и при этом не сразу загружать их все, а нужные подгружать когда нужно, а просмотренные выгружать из памяти

    2. собрать это в видос и запустить его на заднем плане

    я сделал бы первый вариант, он гибче. в первом варианте ничего не надо дополнительно собирать если кол-во кадров и/или сами кадры изменятся

    //как-то так должен выглядеть MyImagesView.m файл
    
    @interface MyImagesView ()
    
    @property (nonatomic, strong) UIImageView *imageView;
    
    @property (nonatomic, assign) int currentImage;
    @property (nonatomic, assign) int totalImages;
    
    @end
    
    @implementation
    
    /*
     * этот метод надо вызывать в таймере. обязательно в Main Thread
     */
    - (void)showNextImage
    {
    	assert([NSThread isMainThread] == YES);
    	
    	self.currentImage ++;
    	if (self.currentImage == self.totalImages)
    	{
    		// что бы отображать картинки циклически
    		self.currentImage = 0;
    	}
    	
    	UIImageView *newImageView = [[UIImageView alloc] initWithFrame:self.bounds];
    	newImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"image_name%i.png", self.currentImage]];
    	
    	[self.imageView removeFromSuperview]; // убираем прирыдущий кадр из view-хи (затираем сильную ссылку номер 1)
    	self.imageView = nil; // убираем сильную ссылку номер два (тут UIImageView должна выгрузиться из памяти, а с ней и UIImage)
    	
    	[self addSubview:newImageView]; // закидываем новый кадр во view-ху (создаём сильную ссылку номер 1)
    	self.imageView = newImageView; // сохраняем ссылку на новый кадр что бы иметь в следующем вызове метода showNextImage ссылку на предыдущий кадр  (создаём сильную ссылку номер 2)
    }
    
    @end


    UPD:
    попробуйте заменить:
    newImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"image_name%i.png", self.currentImage]];
    на:
    NSString *imageName = [NSString stringWithFormat:@"image_name%i", self.currentImage];
    newImageView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:@"png"]];
    Ответ написан
  • MVC в IOS: может ли Model иметь Delegate к контролеру?

    morozovdenis
    @morozovdenis
    Любому объекту вы можете присваивать в делегат любой другой объект, это не нарушает ни какие другие паттерны и т.п.

    //файл A.h
    
    @protocol ADelegate <NSObject>
    
    - (void)aDelegateMethod;
    
    @end
    
    @interface A : NSObject
    
    @property (nonatomic, weak) id<ADelegate> delegate;
    /*
    Описывая делегат таким образом мы скрываем объект за протоколом ADelegate.
    В вашем случае модель не будет знать что у неё делегат это контроллер, модель будет
    думать что там есть некий объект который отвечает на ADelegate протокол и кто там конкретно не важно
    */
    
    @end


    //файл B.h
    
    #import "A.h"
    
    @interface B : NSObject <ADelegate>
    
    @end


    //файл B.m
    
    @implementation B
    
    - (void)foo
    {
        A *a = [A new];
        a.delegate = self;
    }
    
    #pragma mark - ADelegate Protocol
    - (void)aDelegateMethod
    {
    }
    
    @end
    Ответ написан
    Комментировать
  • Как разобратся с моим кодом?

    morozovdenis
    @morozovdenis
    NSString * hexFromDex(int a)
    {
    	return [NSString stringWithFormat:@"%X", a];
    }
    Ответ написан
    Комментировать